unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Emacs-Guix released outside from Guix
@ 2016-12-15 14:48 Alex Kost
  2016-12-15 14:48 ` [PATCH 1/2] gnu: Add emacs-bui Alex Kost
                   ` (5 more replies)
  0 siblings, 6 replies; 30+ messages in thread
From: Alex Kost @ 2016-12-15 14:48 UTC (permalink / raw)
  To: guix-devel

Hello, I've been working on Emacs interface outside from the Guix repo
for some time, I mean I'm not going to maintain it inside Guix, sorry :-(

The main reason, is, well, inconvenience for me: I don't like to bother
people with patches, etc.  I tried to explain it at
<http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.
There are 2 more reasons above that:

- I'd like to make it available on MELPA (people asked about it several
  times in the past);

- Currently, to be able to use it on non-GuixSD system, a user has to
  install 'guix' package into their profile.  This has never looked good
  to me (installing a whole guix only for a small part of it). I would
  prefer to make "guix package -i emacs-guix" possible instead.

So I'd like to add 'emacs-guix' package (the current patchset) and to
remove it from the Guix source tree, if you don't mind.

The code of Emacs-Guix can be found on github¹ or notabug².  I've just
made a release (v0.2); and I'm going to send a message with the summary
of changes later.

¹ https://github.com/alezost/guix.el
² https://notabug.org/alezost/emacs-guix

I'm also sending the following patches:

[PATCH 1/2] gnu: Add emacs-bui.
[PATCH 2/2] gnu: Add emacs-guix.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/2] gnu: Add emacs-bui.
  2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
@ 2016-12-15 14:48 ` Alex Kost
  2016-12-15 17:21   ` Ludovic Courtès
  2016-12-15 14:48 ` [PATCH 2/2] gnu: Add emacs-guix Alex Kost
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-15 14:48 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/emacs.scm (emacs-bui): New variable.
---
 gnu/packages/emacs.scm | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index 5e6b99f..d95c683 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -1245,6 +1245,30 @@ and stored in memory.")
     (description "This package provides a modern list API library for Emacs.")
     (license license:gpl3+)))
 
+(define-public emacs-bui
+  (package
+    (name "emacs-bui")
+    (version "1.0.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/alezost/bui.el/archive/v"
+                    version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0vsh1v99xxm6hhqp0vg9fbs230kawa7xb5dnd8fidf3vwm622aqh"))))
+    (build-system emacs-build-system)
+    (propagated-inputs
+     `(("dash" ,emacs-dash)))
+    (home-page "https://github.com/alezost/bui.el")
+    (synopsis "Buffer interface library for Emacs")
+    (description
+     "BUI (Buffer User Interface) is a library for making @code{list} and
+@code{info} interfaces to display an arbitrary data of the same
+type, for example: packages, buffers, files, etc.")
+    (license license:gpl3+)))
+
 (define-public emacs-d-mode
   (package
     (name "emacs-d-mode")
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 2/2] gnu: Add emacs-guix.
  2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
  2016-12-15 14:48 ` [PATCH 1/2] gnu: Add emacs-bui Alex Kost
@ 2016-12-15 14:48 ` Alex Kost
  2016-12-15 17:22   ` Ludovic Courtès
  2016-12-15 17:39 ` Emacs-Guix released outside from Guix Ludovic Courtès
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-15 14:48 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/emacs.scm (emacs-guix): New variable.
---
 gnu/packages/emacs.scm | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index d95c683..eea20d0 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -1269,6 +1269,59 @@ and stored in memory.")
 type, for example: packages, buffers, files, etc.")
     (license license:gpl3+)))
 
+(define-public emacs-guix
+  (package
+    (name "emacs-guix")
+    (version "0.2")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://github.com/alezost/guix.el"
+                                  "/releases/download/v" version
+                                  "/emacs-guix-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0h168597am5vcix149l27g876v4f5yqwx8v0s9mmsdva1qqcq5s5"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:configure-flags
+       (let ((guix        (assoc-ref %build-inputs "guix"))
+             (geiser      (assoc-ref %build-inputs "geiser"))
+             (dash        (assoc-ref %build-inputs "dash"))
+             (bui         (assoc-ref %build-inputs "bui"))
+             (magit-popup (assoc-ref %build-inputs "magit-popup"))
+             (site-lisp   "/share/emacs/site-lisp"))
+         (list (string-append "--with-guix-site-dir="
+                              guix "/share/guile/site/2.0")
+               (string-append "--with-geiser-lispdir=" geiser site-lisp)
+               (string-append "--with-dash-lispdir="
+                              dash site-lisp "/guix.d/dash-"
+                              ,(package-version emacs-dash))
+               (string-append "--with-bui-lispdir="
+                              bui site-lisp "/guix.d/bui-"
+                              ,(package-version emacs-bui))
+               (string-append "--with-popup-lispdir="
+                              magit-popup site-lisp "/guix.d/magit-popup-"
+                              ,(package-version emacs-magit-popup))))))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("emacs" ,emacs-minimal)))
+    (inputs
+     `(("guile" ,guile-2.0)
+       ("guix" ,guix)))
+    (propagated-inputs
+     `(("geiser" ,geiser)
+       ("dash" ,emacs-dash)
+       ("bui" ,emacs-bui)
+       ("magit-popup" ,emacs-magit-popup)))
+    (home-page "https://github.com/alezost/guix.el")
+    (synopsis "Emacs interface for GNU Guix")
+    (description
+     "Emacs-Guix provides a visual interface, tools and features for the
+GNU Guix package manager.  Particularly, it allows you to do various
+package management tasks from Emacs.  To begin with, run @code{M-x
+guix-help} command.")
+    (license license:gpl3+)))
+
 (define-public emacs-d-mode
   (package
     (name "emacs-d-mode")
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/2] gnu: Add emacs-bui.
  2016-12-15 14:48 ` [PATCH 1/2] gnu: Add emacs-bui Alex Kost
@ 2016-12-15 17:21   ` Ludovic Courtès
  0 siblings, 0 replies; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-15 17:21 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Alex Kost <alezost@gmail.com> skribis:

> * gnu/packages/emacs.scm (emacs-bui): New variable.

OK!

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 2/2] gnu: Add emacs-guix.
  2016-12-15 14:48 ` [PATCH 2/2] gnu: Add emacs-guix Alex Kost
@ 2016-12-15 17:22   ` Ludovic Courtès
  0 siblings, 0 replies; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-15 17:22 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Alex Kost <alezost@gmail.com> skribis:

> * gnu/packages/emacs.scm (emacs-guix): New variable.

OK!

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
  2016-12-15 14:48 ` [PATCH 1/2] gnu: Add emacs-bui Alex Kost
  2016-12-15 14:48 ` [PATCH 2/2] gnu: Add emacs-guix Alex Kost
@ 2016-12-15 17:39 ` Ludovic Courtès
  2016-12-16  0:37   ` Ricardo Wurmus
  2016-12-17  8:19   ` Alex Kost
  2016-12-17  9:13 ` Alex Kost
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-15 17:39 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Hi Alex!

Alex Kost <alezost@gmail.com> skribis:

> Hello, I've been working on Emacs interface outside from the Guix repo
> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>
> The main reason, is, well, inconvenience for me: I don't like to bother
> people with patches, etc.  I tried to explain it at
> <http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.

As someone who’s always trusted you to do the right thing, I’m of course
disappointed that we Guix folks didn’t get notified nor consulted before
the fact.  I would also have loved a reply to my message back then¹.
That’s your choice though.

¹ https://lists.gnu.org/archive/html/guix-devel/2016-07/msg01110.html

> There are 2 more reasons above that:
>
> - I'd like to make it available on MELPA (people asked about it several
>   times in the past);

This is surprising: I’d expect Guix users to install it with Guix, and
non-Guix users to, well, not care about Guix.

> - Currently, to be able to use it on non-GuixSD system, a user has to
>   install 'guix' package into their profile.  This has never looked good
>   to me (installing a whole guix only for a small part of it). I would
>   prefer to make "guix package -i emacs-guix" possible instead.

OK.

This change will prevent joint feature development (updating
completions, ‘emacs-build-system’ and how it interacts with the Emacs
UI, M-x guix, cross-cutting changes to the UI, and so on).  This isn’t
good news for users.

Breakage will occasionally occur as the Guix APIs change, which will
make us all a bit sad.  What are your thoughts?

> So I'd like to add 'emacs-guix' package (the current patchset) and to
> remove it from the Guix source tree, if you don't mind.

I think “if you don’t mind” is misplaced.

> The code of Emacs-Guix can be found on github¹ or notabug².  I've just
> made a release (v0.2); and I'm going to send a message with the summary
> of changes later.
>
> ¹ https://github.com/alezost/guix.el
> ² https://notabug.org/alezost/emacs-guix
>
> I'm also sending the following patches:
>
> [PATCH 1/2] gnu: Add emacs-bui.
> [PATCH 2/2] gnu: Add emacs-guix.

OK!

I’ll let you take care of the actual removal, along with update to the
Texinfo cross-references and doc/htmlxref.cnf (assuming the manual will
be available on-line.)  I think it would help users to keep
cross-references between the two manuals.

We need to see what Ricardo thinks and whether or not this can be done
before 0.12, which is slated for sometime next week.

Keep up the great Emacs work.  Long live guix.el!

Ludo’.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-15 17:39 ` Emacs-Guix released outside from Guix Ludovic Courtès
@ 2016-12-16  0:37   ` Ricardo Wurmus
  2016-12-16 16:44     ` Ludovic Courtès
  2016-12-17  8:38     ` Alex Kost
  2016-12-17  8:19   ` Alex Kost
  1 sibling, 2 replies; 30+ messages in thread
From: Ricardo Wurmus @ 2016-12-16  0:37 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel, Alex Kost


Hi Alex,

Ludovic Courtès <ludo@gnu.org> writes:

> Alex Kost <alezost@gmail.com> skribis:
>
>> Hello, I've been working on Emacs interface outside from the Guix repo
>> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>>
>> The main reason, is, well, inconvenience for me: I don't like to bother
>> people with patches, etc.  I tried to explain it at
>> <http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.
>
> As someone who’s always trusted you to do the right thing, I’m of course
> disappointed that we Guix folks didn’t get notified nor consulted before
> the fact.  I would also have loved a reply to my message back then¹.
> That’s your choice though.
>
> ¹ https://lists.gnu.org/archive/html/guix-devel/2016-07/msg01110.html

First of all, let me tell you that I really appreciate your work on
guix.el!  It’s excellent and makes me feel even more at home in Emacs.

I whole-heartedly second what Ludo wrote and just now and back then:

    It would be a great loss and a technical hindrance if guix.el was moved
    out of Guix.  I don’t want that to happen, so let me know what the
    ransom should be!  ;-)

We’d love for guix.el to stay.  You can already modify the code as you
deem appropriate without having to worry about a veto from any of us.

> Breakage will occasionally occur as the Guix APIs change, which will
> make us all a bit sad.  What are your thoughts?

This is the biggie for me.  Having the Emacs interface so closely
integrated with the rest of Guix ensured that we wouldn’t have to worry
about breakage.  In my opinion this move increases the friction for the
users that most care about guix.el for the dubious improvement of
offering a slimmer guix.el to people who … don’t use Guix.

I feel like I’m missing something here.

> I’ll let you take care of the actual removal, along with update to the
> Texinfo cross-references and doc/htmlxref.cnf (assuming the manual will
> be available on-line.)  I think it would help users to keep
> cross-references between the two manuals.
>
> We need to see what Ricardo thinks and whether or not this can be done
> before 0.12, which is slated for sometime next week.

Yes, I’ll start preparing for the release (going through the motions) on
the weekend, so that the actual tagging and uploading can happen on the
20th (busy on the 19th) if all goes well.

If you go through with the move please double check that the Guix
sources are in a state that’s ready for release.  It would be terrible
to have a botched release.  (Frankly, I’m a little uncomfortable about
such a big change right before the release, but maybe I’m just being
nervous about doing the release myself this time…)

-- 
Ricardo
  
  GPG: BCA6 89B6 3655 3801 C3C6  2150 197A 5888 235F ACAC
  http://elephly.net

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-16  0:37   ` Ricardo Wurmus
@ 2016-12-16 16:44     ` Ludovic Courtès
  2016-12-17  8:17       ` Alex Kost
  2016-12-17  8:38     ` Alex Kost
  1 sibling, 1 reply; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-16 16:44 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: guix-devel, Alex Kost

Howdy!

Ricardo Wurmus <rekado@elephly.net> skribis:

> If you go through with the move please double check that the Guix
> sources are in a state that’s ready for release.  It would be terrible
> to have a botched release.  (Frankly, I’m a little uncomfortable about
> such a big change right before the release, but maybe I’m just being
> nervous about doing the release myself this time…)

It’s fine to postpone the change until after the release if we’re afraid
of last-minute breakage (which is not unlikely).

Ludo’.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-16 16:44     ` Ludovic Courtès
@ 2016-12-17  8:17       ` Alex Kost
  0 siblings, 0 replies; 30+ messages in thread
From: Alex Kost @ 2016-12-17  8:17 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Ludovic Courtès (2016-12-16 17:44 +0100) wrote:

> Howdy!
>
> Ricardo Wurmus <rekado@elephly.net> skribis:
>
>> If you go through with the move please double check that the Guix
>> sources are in a state that’s ready for release.  It would be terrible
>> to have a botched release.  (Frankly, I’m a little uncomfortable about
>> such a big change right before the release, but maybe I’m just being
>> nervous about doing the release myself this time…)
>
> It’s fine to postpone the change until after the release if we’re afraid
> of last-minute breakage (which is not unlikely).

I agree, removing "guix.el" code and related changes can happen later,
no hurry about it, thanks!

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-15 17:39 ` Emacs-Guix released outside from Guix Ludovic Courtès
  2016-12-16  0:37   ` Ricardo Wurmus
@ 2016-12-17  8:19   ` Alex Kost
  2016-12-18 10:32     ` Ludovic Courtès
  2016-12-18 15:35     ` Pjotr Prins
  1 sibling, 2 replies; 30+ messages in thread
From: Alex Kost @ 2016-12-17  8:19 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Ludovic Courtès (2016-12-15 18:39 +0100) wrote:

> Hi Alex!
>
> Alex Kost <alezost@gmail.com> skribis:
>
>> Hello, I've been working on Emacs interface outside from the Guix repo
>> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>>
>> The main reason, is, well, inconvenience for me: I don't like to bother
>> people with patches, etc.  I tried to explain it at
>> <http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.
>
> As someone who’s always trusted you to do the right thing, I’m of course
> disappointed that we Guix folks didn’t get notified nor consulted before
> the fact.  I would also have loved a reply to my message back then¹.
> That’s your choice though.
>
> ¹ https://lists.gnu.org/archive/html/guix-devel/2016-07/msg01110.html

I'm sorry for not answering, I thought I was clear at the time.  I
always feel uncomfortable to send patches or to push commits to the Guix
repo.  I can't explain it properly, it's just painful all the time; but
more importantly, it slowed down the development, as I often decided not
to do small changes.  Contrary, I made more commits to the Emacs-Guix
source tree in the past month, than to the Guix repo during the whole
year.

>> There are 2 more reasons above that:
>>
>> - I'd like to make it available on MELPA (people asked about it several
>>   times in the past);
>
> This is surprising: I’d expect Guix users to install it with Guix, and
> non-Guix users to, well, not care about Guix.

It's not surprising for me: there are people who prefer to install Emacs
packages using Emacs build system, so providing this way to install
"guix.el" seems the right thing for me.

>> - Currently, to be able to use it on non-GuixSD system, a user has to
>>   install 'guix' package into their profile.  This has never looked good
>>   to me (installing a whole guix only for a small part of it). I would
>>   prefer to make "guix package -i emacs-guix" possible instead.
>
> OK.
>
> This change will prevent joint feature development (updating
> completions, ‘emacs-build-system’ and how it interacts with the Emacs
> UI, M-x guix, cross-cutting changes to the UI, and so on).  This isn’t
> good news for users.
>
> Breakage will occasionally occur as the Guix APIs change, which will
> make us all a bit sad.  What are your thoughts?

Well, I was going to make a release and to update the 'emacs-guix'
package after fixing such a breakage.  Actually this way doesn't look
worse for me: when breakages happened in the past, the only way to fix
it was to update 'guix-devel' package.

>> So I'd like to add 'emacs-guix' package (the current patchset) and to
>> remove it from the Guix source tree, if you don't mind.
>
> I think “if you don’t mind” is misplaced.

No, it's not misplaced; not sure what you mean.

>> I'm also sending the following patches:
>>
>> [PATCH 1/2] gnu: Add emacs-bui.
>> [PATCH 2/2] gnu: Add emacs-guix.
>
> OK!

Thanks!  Applied.

> I’ll let you take care of the actual removal, along with update to the
> Texinfo cross-references and doc/htmlxref.cnf (assuming the manual will
> be available on-line.)

Ahem, it will not, at least not soon.

> I think it would help users to keep
> cross-references between the two manuals.

Emacs-Guix manual has many links to the Guix manual, but I think a
single mention of Emacs-Guix in the Guix manual will be enough.  I have
not looked at updating cross-references in the Guix manual yet, though.

> We need to see what Ricardo thinks and whether or not this can be done
> before 0.12, which is slated for sometime next week.

I think this removal can be made later.

> Keep up the great Emacs work.  Long live guix.el!

Thanks, I keep up.

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-16  0:37   ` Ricardo Wurmus
  2016-12-16 16:44     ` Ludovic Courtès
@ 2016-12-17  8:38     ` Alex Kost
  2016-12-17  9:00       ` John Darrington
  1 sibling, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-17  8:38 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: guix-devel

Ricardo Wurmus (2016-12-16 01:37 +0100) wrote:

> Hi Alex,
>
> Ludovic Courtès <ludo@gnu.org> writes:
>
>> Alex Kost <alezost@gmail.com> skribis:
>>
>>> Hello, I've been working on Emacs interface outside from the Guix repo
>>> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>>>
>>> The main reason, is, well, inconvenience for me: I don't like to bother
>>> people with patches, etc.  I tried to explain it at
>>> <http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.
>>
>> As someone who’s always trusted you to do the right thing, I’m of course
>> disappointed that we Guix folks didn’t get notified nor consulted before
>> the fact.  I would also have loved a reply to my message back then¹.
>> That’s your choice though.
>>
>> ¹ https://lists.gnu.org/archive/html/guix-devel/2016-07/msg01110.html
>
> First of all, let me tell you that I really appreciate your work on
> guix.el!  It’s excellent and makes me feel even more at home in Emacs.
>
> I whole-heartedly second what Ludo wrote and just now and back then:
>
>     It would be a great loss and a technical hindrance if guix.el was moved
>     out of Guix.  I don’t want that to happen, so let me know what the
>     ransom should be!  ;-)

There shouldn't be any ransom!  I just didn't feel I had enough freedom
when I was working on it inside Guix.

> We’d love for guix.el to stay.  You can already modify the code as you
> deem appropriate without having to worry about a veto from any of us.

Sorry, but I have already pushed too much effort making it a separate
project, and it has changed quite a lot comparing to what we have in a
Guix repo.

>> Breakage will occasionally occur as the Guix APIs change, which will
>> make us all a bit sad.  What are your thoughts?
>
> This is the biggie for me.  Having the Emacs interface so closely
> integrated with the rest of Guix ensured that we wouldn’t have to worry
> about breakage.

How could we be ensured?  When a breakage happened in the past, an
according fix had to be done in the guix repo, and it wasn't available
for users until updating 'guix-devel' package.  Now when a breakage will
happen, an according fix will be done in the emacs-guix repo, and it
will be available for MELPA/Quelpa users right away.

> In my opinion this move increases the friction for the
> users that most care about guix.el for the dubious improvement of
> offering a slimmer guix.el to people who … don’t use Guix.

People can use Guix, but they can still prefer to install Emacs packages
via elpa, not via Guix.

>> I’ll let you take care of the actual removal, along with update to the
>> Texinfo cross-references and doc/htmlxref.cnf (assuming the manual will
>> be available on-line.)  I think it would help users to keep
>> cross-references between the two manuals.
>>
>> We need to see what Ricardo thinks and whether or not this can be done
>> before 0.12, which is slated for sometime next week.
>
> Yes, I’ll start preparing for the release (going through the motions) on
> the weekend, so that the actual tagging and uploading can happen on the
> 20th (busy on the 19th) if all goes well.
>
> If you go through with the move please double check that the Guix
> sources are in a state that’s ready for release.  It would be terrible
> to have a botched release.  (Frankly, I’m a little uncomfortable about
> such a big change right before the release, but maybe I’m just being
> nervous about doing the release myself this time…)

I'm going to send "removal" patches after the release.  BTW thank you
for taking care of the release!

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-17  8:38     ` Alex Kost
@ 2016-12-17  9:00       ` John Darrington
  2016-12-19 21:38         ` Alex Kost
  0 siblings, 1 reply; 30+ messages in thread
From: John Darrington @ 2016-12-17  9:00 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 862 bytes --]

On Sat, Dec 17, 2016 at 11:38:13AM +0300, Alex Kost wrote:

     >     It would be a great loss and a technical hindrance if guix.el was moved
     >     out of Guix.  I don???t want that to happen, so let me know what the
     >     ransom should be!  ;-)
     
     There shouldn't be any ransom!  I just didn't feel I had enough freedom
     when I was working on it inside Guix.


Could you elaborate here?  What circumstances made you feel this way?  Have there
been specific events which made you feel your freedom was being limited?  What
would you have liked to have seen done differently?

J'
     
     

-- 
Avoid eavesdropping.  Send strong encrypted email.
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://sks-keyservers.net or any PGP keyserver for public key.


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
                   ` (2 preceding siblings ...)
  2016-12-15 17:39 ` Emacs-Guix released outside from Guix Ludovic Courtès
@ 2016-12-17  9:13 ` Alex Kost
  2016-12-22  0:18   ` myglc2
  2016-12-22 10:35 ` [PATCH] Remove Emacs interface Alex Kost
  2017-01-06 15:50 ` Emacs-Guix released outside from Guix Thompson, David
  5 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-17  9:13 UTC (permalink / raw)
  To: guix-devel

I have committed 'emacs-guix' package, so after "guix pull" or if you
use the git checkout, you may try it with:

  guix package -i emacs-guix

Just make sure it has a priority over the elisp code from Guix.
"M-x list-load-path-shadows" should help you to figure it out.

Now a bit about the changes.

1. At first, there are 2 new commands:

- M-x guix-help

  I think it may be the most useful command as it shows a summary of all
  the rest available commands.

- M-x guix-profiles

  It displays a list of your Guix profiles.  It's probably not very
  useful if you have a single profile, but if you manage multiple
  profiles, it can be really helpful (well, it's my favourite command as
  I use several profiles).  To add more profiles, set 'guix-profiles'
  variable.

  In this list you can display packages/generations with "P"/"G" keys.
  See also the manual entry: (info "(emacs-guix) Profiles")

2. Secondly, you may be surprised that RET does not display packages
anymore in a list of generations (M-x guix-generations) or licenses (M-x
guix-licenses).  Now "P" key can be used anywhere (where appropriate,
i.e. in a list of profiles, generations, licenses or locations) to
display packages.

3. Also I should mention that 'guix-devel-mode' and
'guix-build-log-minor-mode' are not enabled in scheme/shell buffers by
default.  If you still wish to have them enabled, use:

  (add-hook 'scheme-mode-hook 'guix-devel-mode)
  (add-hook 'shell-mode-hook 'guix-build-log-minor-mode)

in your emacs config.

4. The rest changes are either visible or internal or not important.
You may look at NEWS file for more or less the full list of changes:
<https://notabug.org/alezost/emacs-guix/raw/master/NEWS>.

Thanks for reading this far :-)

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-17  8:19   ` Alex Kost
@ 2016-12-18 10:32     ` Ludovic Courtès
  2016-12-18 15:47       ` Adonay Felipe Nogueira
                         ` (2 more replies)
  2016-12-18 15:35     ` Pjotr Prins
  1 sibling, 3 replies; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-18 10:32 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Hi Alex,

Alex Kost <alezost@gmail.com> skribis:

> Ludovic Courtès (2016-12-15 18:39 +0100) wrote:
>
>> Hi Alex!
>>
>> Alex Kost <alezost@gmail.com> skribis:
>>
>>> Hello, I've been working on Emacs interface outside from the Guix repo
>>> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>>>
>>> The main reason, is, well, inconvenience for me: I don't like to bother
>>> people with patches, etc.  I tried to explain it at
>>> <http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.
>>
>> As someone who’s always trusted you to do the right thing, I’m of course
>> disappointed that we Guix folks didn’t get notified nor consulted before
>> the fact.  I would also have loved a reply to my message back then¹.
>> That’s your choice though.
>>
>> ¹ https://lists.gnu.org/archive/html/guix-devel/2016-07/msg01110.html
>
> I'm sorry for not answering, I thought I was clear at the time.

I thought I was clear too, that message called for your feedback (and
this one does too!).  Dialog is a two-way street.

> I always feel uncomfortable to send patches or to push commits to the
> Guix repo.  I can't explain it properly, it's just painful all the
> time; but more importantly, it slowed down the development, as I often
> decided not to do small changes.  Contrary, I made more commits to the
> Emacs-Guix source tree in the past month, than to the Guix repo during
> the whole year.

I have the same questions as John: what is it that made you feel
uncomfortable?  I stated clearly multiple times that you are effectively
“sudoer” on this code.

Let’s reflect on this for all the future Alexes that come around.  If
you are in my position, what do you do to make it so that the next Alex
feels comfortable and happy with this workflow?  What does it take to
avoid an “Alexit”?  :-)

That’s an honest question: I cannot state what I did wrong, but I’d like
to learn so it doesn’t happen again.

>> This change will prevent joint feature development (updating
>> completions, ‘emacs-build-system’ and how it interacts with the Emacs
>> UI, M-x guix, cross-cutting changes to the UI, and so on).  This isn’t
>> good news for users.
>>
>> Breakage will occasionally occur as the Guix APIs change, which will
>> make us all a bit sad.  What are your thoughts?
>
> Well, I was going to make a release and to update the 'emacs-guix'
> package after fixing such a breakage.  Actually this way doesn't look
> worse for me: when breakages happened in the past, the only way to fix
> it was to update 'guix-devel' package.

That will be even harder with separate projects.

What about joint feature development (see above)?

>>> So I'd like to add 'emacs-guix' package (the current patchset) and to
>>> remove it from the Guix source tree, if you don't mind.
>>
>> I think “if you don’t mind” is misplaced.
>
> No, it's not misplaced; not sure what you mean.

Saying “if you don’t mind” for a decision that is effectively imposed on
others without discussion is harsh, to put it mildly.

>> I’ll let you take care of the actual removal, along with update to the
>> Texinfo cross-references and doc/htmlxref.cnf (assuming the manual will
>> be available on-line.)
>
> Ahem, it will not, at least not soon.
>
>> I think it would help users to keep
>> cross-references between the two manuals.
>
> Emacs-Guix manual has many links to the Guix manual, but I think a
> single mention of Emacs-Guix in the Guix manual will be enough.  I have
> not looked at updating cross-references in the Guix manual yet, though.

Sadness.  I think users won’t be happier.  :-/

Pardon me for being grumpy, I’m just feeling sad and frustrated.

Ludo’.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-17  8:19   ` Alex Kost
  2016-12-18 10:32     ` Ludovic Courtès
@ 2016-12-18 15:35     ` Pjotr Prins
  1 sibling, 0 replies; 30+ messages in thread
From: Pjotr Prins @ 2016-12-18 15:35 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

On Sat, Dec 17, 2016 at 11:19:57AM +0300, Alex Kost wrote:
> I'm sorry for not answering, I thought I was clear at the time.  I
> always feel uncomfortable to send patches or to push commits to the Guix
> repo.  I can't explain it properly, it's just painful all the time; but
> more importantly, it slowed down the development, as I often decided not
> to do small changes.  Contrary, I made more commits to the Emacs-Guix
> source tree in the past month, than to the Guix repo during the whole
> year.

Alex, I completely understand. The demands on patches are high and I
have stopped submitting myself even though I work on Guix all the
time. Best is to have your own tree. Tying versions to Guix is trivial
- that is the point of Guix, rather ;).

Making emacs-guix a Guix package is a fine alternative. If someone
finds it that important to host on main he/she can still do that, but
I have trouble seeing the need.

Pj.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-18 10:32     ` Ludovic Courtès
@ 2016-12-18 15:47       ` Adonay Felipe Nogueira
  2016-12-19  5:00         ` Emacs-Guix released outside from Guix - or why I am not sending patches in Pjotr Prins
  2016-12-19 21:47       ` Emacs-Guix released outside from Guix Alex Kost
  2016-12-22 19:09       ` myglc2
  2 siblings, 1 reply; 30+ messages in thread
From: Adonay Felipe Nogueira @ 2016-12-18 15:47 UTC (permalink / raw)
  To: guix-devel

I suspect that he's more used to have "push" permissions to repositories
instead of submitting patches.

I, personally, like to work with patches because this allows me to
submit them directly to people involved in the project in cases the
project in question requires non-(free/libre) software (written in
JavaScript) in order to submit things (of course, I'm **not** talking
about Guix). Also, patch submissions don't require accounts in such
places as long as you have a way to contact at least one developer by
email.

Also, I also like patches because people can state their opinions about
what I do and even give me some improvement hints instead of having to
do various push requests in order to make such improvements.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix - or why I am not sending patches in
  2016-12-18 15:47       ` Adonay Felipe Nogueira
@ 2016-12-19  5:00         ` Pjotr Prins
  0 siblings, 0 replies; 30+ messages in thread
From: Pjotr Prins @ 2016-12-19  5:00 UTC (permalink / raw)
  To: Adonay Felipe Nogueira; +Cc: guix-devel

On Sun, Dec 18, 2016 at 01:47:18PM -0200, Adonay Felipe Nogueira wrote:
> I suspect that he's more used to have "push" permissions to repositories
> instead of submitting patches.

In principle that should not stop working you on your own branch. You
can push and collect your commits into a compiled patch later. That
does not stop the flow of work.

> I, personally, like to work with patches because this allows me to
> submit them directly to people involved in the project in cases the
> project in question requires non-(free/libre) software (written in
> JavaScript) in order to submit things (of course, I'm **not** talking
> about Guix). Also, patch submissions don't require accounts in such
> places as long as you have a way to contact at least one developer by
> email.
> 
> Also, I also like patches because people can state their opinions about
> what I do and even give me some improvement hints instead of having to
> do various push requests in order to make such improvements.

Sure. It can be a learning process which is great. I tried. There are
three problems (also with patches committed for packages):

1. The author may not agree with the imposed strictness or rules of
   patches

2. The turnaround of accepting patches can be a long time

3. Fixing patches on things you don't agree on (or see the importance
   of) is tedious. Very tedious.

That is why I stopped. I rather spend my time coding and documenting.
Personally I also think the threshold is too high to newcomers. 

Obviously others disagree with the above. I may be more sloppy in my
way of coding. I think that if code reads well it is acceptable. I
don't reject things because of spacing or lack comments. I don't
reject things because they are suboptimal (I should stop being a GSoC
mentor if that was the case). I believe that code can be changed and
improved incrementally both by the author and by others. I don't care
others see my short comings. In other words, I am one who plays by his
own rules.

In short, *I* know why *I* am not sending patches in. Even though I
have a long list of packages that *could* go in and arguably should.

This is my annual message on why I think the process may be
improved ;). Maybe we should have a 'sloppy' branch for people like
me. guix channels may help people like me too. I am convinced we could
have double the growth if we were good at attracting and retaining
contributions.

Guix will succeed. I am not arguing we should compromise for
correctness on trunk. But there ought to be ways to help sloppy
contributors ;). Otherwise I'll never contribute to a GNU project. If
the project does not care - who am I to care?

Pj.

-- 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-17  9:00       ` John Darrington
@ 2016-12-19 21:38         ` Alex Kost
  0 siblings, 0 replies; 30+ messages in thread
From: Alex Kost @ 2016-12-19 21:38 UTC (permalink / raw)
  To: John Darrington; +Cc: guix-devel

John Darrington (2016-12-17 10:00 +0100) wrote:

> On Sat, Dec 17, 2016 at 11:38:13AM +0300, Alex Kost wrote:
>
>      >     It would be a great loss and a technical hindrance if guix.el was moved
>      >     out of Guix.  I don???t want that to happen, so let me know what the
>      >     ransom should be!  ;-)
>
>      There shouldn't be any ransom!  I just didn't feel I had enough freedom
>      when I was working on it inside Guix.
>
>
> Could you elaborate here?  What circumstances made you feel this way?

There are no any circumstances.  It's just that when you maintain your
own project, you can do whatever seems appropriate to you; while with a
community-driven (I don't know a correct term) project, you have to…
well, to communicate – the thing I don't like quite a lot.  So it's not
a Guix community problem!

> Have there been specific events which made you feel your freedom was
> being limited?

No, not at all!  It's just my attitude as I tried to explain.

> What would you have liked to have seen done differently?

Well, I agree with Pjotr's points.  I think the most important is that
all the existing rules make a very high barrier to overcome for the
potential contributors.  I'm not talking about myself, I'm fine with the
rules, but I see how all these guidelines, coding styles and sending
patches to the mailing list can scare people.

But all this has nothing to do with separating Emacs-Guix.  It's just my
egoism: I want to push commits without discussing (or simple sending
patches).

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-18 10:32     ` Ludovic Courtès
  2016-12-18 15:47       ` Adonay Felipe Nogueira
@ 2016-12-19 21:47       ` Alex Kost
  2016-12-20 13:58         ` Ludovic Courtès
  2016-12-22 19:09       ` myglc2
  2 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-19 21:47 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Ludovic Courtès (2016-12-18 11:32 +0100) wrote:

> Hi Alex,
>
> Alex Kost <alezost@gmail.com> skribis:
>
>> Ludovic Courtès (2016-12-15 18:39 +0100) wrote:
>>
>>> Hi Alex!
>>>
>>> Alex Kost <alezost@gmail.com> skribis:
>>>
>>>> Hello, I've been working on Emacs interface outside from the Guix repo
>>>> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>>>>
>>>> The main reason, is, well, inconvenience for me: I don't like to bother
>>>> people with patches, etc.  I tried to explain it at
>>>> <http://lists.gnu.org/archive/html/guix-devel/2016-07/msg01091.html>.
>>>
>>> As someone who’s always trusted you to do the right thing, I’m of course
>>> disappointed that we Guix folks didn’t get notified nor consulted before
>>> the fact.  I would also have loved a reply to my message back then¹.
>>> That’s your choice though.
>>>
>>> ¹ https://lists.gnu.org/archive/html/guix-devel/2016-07/msg01110.html
>>
>> I'm sorry for not answering, I thought I was clear at the time.
>
> I thought I was clear too, that message called for your feedback (and
> this one does too!).  Dialog is a two-way street.

But I answered this time!  Sorry if I wasn't clear enough, I tried to
explain my reasons several times, but I can try again.

>> I always feel uncomfortable to send patches or to push commits to the
>> Guix repo.  I can't explain it properly, it's just painful all the
>> time; but more importantly, it slowed down the development, as I often
>> decided not to do small changes.  Contrary, I made more commits to the
>> Emacs-Guix source tree in the past month, than to the Guix repo during
>> the whole year.
>
> I have the same questions as John: what is it that made you feel
> uncomfortable?  I stated clearly multiple times that you are effectively
> “sudoer” on this code.

It's not enough for me: developing an own project is incomparably easier
for me than participating in other people's project.

> Let’s reflect on this for all the future Alexes that come around.  If
> you are in my position, what do you do to make it so that the next Alex
> feels comfortable and happy with this workflow?  What does it take to
> avoid an “Alexit”?  :-)
>
> That’s an honest question: I cannot state what I did wrong, but I’d like
> to learn so it doesn’t happen again.

You did nothing wrong!  It's a nature of such Alexes: we don't like to
communicate with people and we try to avoid it as much as possible.

>>> This change will prevent joint feature development (updating
>>> completions, ‘emacs-build-system’ and how it interacts with the Emacs
>>> UI, M-x guix, cross-cutting changes to the UI, and so on).  This isn’t
>>> good news for users.
>>>
>>> Breakage will occasionally occur as the Guix APIs change, which will
>>> make us all a bit sad.  What are your thoughts?
>>
>> Well, I was going to make a release and to update the 'emacs-guix'
>> package after fixing such a breakage.  Actually this way doesn't look
>> worse for me: when breakages happened in the past, the only way to fix
>> it was to update 'guix-devel' package.
>
> That will be even harder with separate projects.
>
> What about joint feature development (see above)?

Well, when I will notice some related change in Guix, I will do an
according change in Emacs-Guix.  Or someone else will report about it.
If no one will notice or report, then it does not matter.

>>>> So I'd like to add 'emacs-guix' package (the current patchset) and to
>>>> remove it from the Guix source tree, if you don't mind.
>>>
>>> I think “if you don’t mind” is misplaced.
>>
>> No, it's not misplaced; not sure what you mean.
>
> Saying “if you don’t mind” for a decision that is effectively imposed on
> others without discussion is harsh, to put it mildly.

When I wrote "I'd like ... if you don't mind", I politely tried to ask
for a permission to add 'emacs-guix' package, as not allowing me to do
that was one of the possible answers.  I didn't discuss my decision
because I don't like discussions.  Besides, it's a one man's self-willed
decision, how other people could change it without tortures?

[...]
> Pardon me for being grumpy, I’m just feeling sad and frustrated.

No problems, it's not a disaster after all.  If you still wish to use
it, you can just install it as you install other Emacs packages.

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-19 21:47       ` Emacs-Guix released outside from Guix Alex Kost
@ 2016-12-20 13:58         ` Ludovic Courtès
  0 siblings, 0 replies; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-20 13:58 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Howdy,

Thanks for taking the time to explain.

Make sure to let us know what new things happen in Emacs-Guix, you know
it has its fan club here!  :-)

Ludo’.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-17  9:13 ` Alex Kost
@ 2016-12-22  0:18   ` myglc2
  2016-12-22  9:15     ` Alex Kost
  0 siblings, 1 reply; 30+ messages in thread
From: myglc2 @ 2016-12-22  0:18 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

On 12/17/2016 at 12:13 Alex Kost writes:

> I have committed 'emacs-guix' package, so after "guix pull" or if you
> use the git checkout, you may try it with:
>
>   guix package -i emacs-guix

Hi Alex,

Tried this on GuixSD 0.12.0 from git and I dig it!

When I google 'guix emacs github' the top hit is ...

GitHub - alezost/guix.el: (OBSOLETE) Emacs interface for Guix ...

... Which is cool, but '(OBSOLETE)' is odd. Maybe it will fix itself?

Have you decided re feedback/support? github issues? mailing list?

Many thanks for continuing to make emacs-guix cooler and cooler!

-George

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-22  0:18   ` myglc2
@ 2016-12-22  9:15     ` Alex Kost
  2016-12-22 15:25       ` myglc2
  0 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-22  9:15 UTC (permalink / raw)
  To: myglc2; +Cc: guix-devel

myglc2 (2016-12-21 19:18 -0500) wrote:

> On 12/17/2016 at 12:13 Alex Kost writes:
>
>> I have committed 'emacs-guix' package, so after "guix pull" or if you
>> use the git checkout, you may try it with:
>>
>>   guix package -i emacs-guix
>
> Hi Alex,
>
> Tried this on GuixSD 0.12.0 from git and I dig it!
>
> When I google 'guix emacs github' the top hit is ...
>
> GitHub - alezost/guix.el: (OBSOLETE) Emacs interface for Guix ...
>
> ... Which is cool, but '(OBSOLETE)' is odd. Maybe it will fix itself?

I'm sure it will fix itself.  I changed this description a week ago (it
was "OBSOLETE" for more than a year); apparently, google does not know
about it yet.

> Have you decided re feedback/support? github issues? mailing list?

Whatever seems appropriate to you: issues or pull requests on
github/notabug, or mailing me directly is OK.  As for using guix-devel
mailing list, I think it's not a suitable place, I would like to avoid
polluting this list with Emacs-Guix stuff.

> Many thanks for continuing to make emacs-guix cooler and cooler!

Thanks, make sure to check "M-x guix-help", if you have not yet.  BTW
I'm going to release 0.2.1 in a few days.  It will have "M-x guix-about"
command, which is not very useful but it's "fancy"... well, I'll make an
announcement about it :-)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH] Remove Emacs interface.
  2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
                   ` (3 preceding siblings ...)
  2016-12-17  9:13 ` Alex Kost
@ 2016-12-22 10:35 ` Alex Kost
  2016-12-29 17:40   ` Ludovic Courtès
  2017-01-06 15:50 ` Emacs-Guix released outside from Guix Thompson, David
  5 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-22 10:35 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 762 bytes --]

The attached patch removes Emacs UI and its documentation (12000 lines
removed, hooray!).  I added the only mention about 'emacs-guix' package
in "Package Management" chapter.

Now 'emacs' directory contains a single git-controlled file -
"guix-emacs.el".  It is used to patch our 'emacs' package (to find emacs
packages in "share/emacs/site-lisp/guix.d").  But it is misplaced.

What about making "gnu/packages/files" (or another dirname) directory,
and putting "guix-emacs.el" and kernel configs ("linux-libre-*.conf")
there?

I mean "gnu/packages/patches" is not always enough, sometimes we want to
use real files in the package recipes (configs for 'linux-libre' or
"guix-emacs.el" for 'emacs'), so having "gnu/packages/files" seems
reasonable to me, WDYT?


[-- Attachment #2: 0001-Remove-Emacs-interface.patch --]
[-- Type: text/x-patch, Size: 480698 bytes --]

From e18fb1722f61161b546219b0fd6a018bd5a01370 Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Thu, 22 Dec 2016 12:47:28 +0300
Subject: [PATCH] Remove Emacs interface.

* emacs/guix-about.el: Remove file.
* emacs/guix-backend.el: Likewise.
* emacs/guix-base.el: Likewise.
* emacs/guix-buffer.el: Likewise.
* emacs/guix-build-log.el: Likewise.
* emacs/guix-command.el: Likewise.
* emacs/guix-config.el.in: Likewise.
* emacs/guix-devel.el: Likewise.
* emacs/guix-entry.el: Likewise.
* emacs/guix-external.el: Likewise.
* emacs/guix-geiser.el: Likewise.
* emacs/guix-guile.el: Likewise.
* emacs/guix-help-vars.el: Likewise.
* emacs/guix-helper.scm.in: Likewise.
* emacs/guix-history.el: Likewise.
* emacs/guix-hydra-build.el: Likewise.
* emacs/guix-hydra-jobset.el: Likewise.
* emacs/guix-hydra.el: Likewise.
* emacs/guix-info.el: Likewise.
* emacs/guix-init.el: Likewise.
* emacs/guix-license.el: Likewise.
* emacs/guix-list.el: Likewise.
* emacs/guix-location.el: Likewise.
* emacs/guix-main.scm: Likewise.
* emacs/guix-messages.el: Likewise.
* emacs/guix-pcomplete.el: Likewise.
* emacs/guix-popup.el: Likewise.
* emacs/guix-prettify.el: Likewise.
* emacs/guix-profiles.el: Likewise.
* emacs/guix-read.el: Likewise.
* emacs/guix-ui-generation.el: Likewise.
* emacs/guix-ui-license.el: Likewise.
* emacs/guix-ui-location.el: Likewise.
* emacs/guix-ui-package.el: Likewise.
* emacs/guix-ui-system-generation.el: Likewise.
* emacs/guix-ui.el: Likewise.
* emacs/guix-utils.el: Likewise.
* emacs/local.mk: Likewise.
* doc/emacs.texi: Likewise.
* doc/guix.texi: Remove cross-references to Emacs nodes.
(Package Management): Mention 'emacs-guix' package.
* doc/contributing.texi (The Perfect Setup): Remove the reference.
* Makefile.am: Remove Emacs stuff.
* configure.ac: Likewise.
* gnu/packages/package-management.scm (guix-0.12.0)[native-inputs]:
Remove "emacs".
[propagated-inputs]: Remove "geiser" and "emacs-magit-popup".
---
 Makefile.am                         |    8 -
 configure.ac                        |   10 -
 doc/contributing.texi               |    3 -
 doc/emacs.texi                      |  881 --------------------------
 doc/guix.texi                       |   51 +-
 emacs/guix-about.el                 |   37 --
 emacs/guix-backend.el               |  393 ------------
 emacs/guix-base.el                  |  377 -----------
 emacs/guix-buffer.el                |  624 ------------------
 emacs/guix-build-log.el             |  381 -----------
 emacs/guix-command.el               |  830 ------------------------
 emacs/guix-config.el.in             |   44 --
 emacs/guix-devel.el                 |  382 -----------
 emacs/guix-entry.el                 |   59 --
 emacs/guix-external.el              |   88 ---
 emacs/guix-geiser.el                |  126 ----
 emacs/guix-guile.el                 |   98 ---
 emacs/guix-help-vars.el             |  108 ----
 emacs/guix-helper.scm.in            |   65 --
 emacs/guix-history.el               |   92 ---
 emacs/guix-hydra-build.el           |  362 -----------
 emacs/guix-hydra-jobset.el          |  162 -----
 emacs/guix-hydra.el                 |  367 -----------
 emacs/guix-info.el                  |  482 --------------
 emacs/guix-init.el                  |    3 -
 emacs/guix-license.el               |   65 --
 emacs/guix-list.el                  |  585 -----------------
 emacs/guix-location.el              |   79 ---
 emacs/guix-main.scm                 | 1163 ----------------------------------
 emacs/guix-messages.el              |  247 --------
 emacs/guix-pcomplete.el             |  370 -----------
 emacs/guix-popup.el                 |   48 --
 emacs/guix-prettify.el              |  210 ------
 emacs/guix-profiles.el              |   77 ---
 emacs/guix-read.el                  |  147 -----
 emacs/guix-ui-generation.el         |  456 --------------
 emacs/guix-ui-license.el            |  150 -----
 emacs/guix-ui-location.el           |   83 ---
 emacs/guix-ui-package.el            | 1191 -----------------------------------
 emacs/guix-ui-system-generation.el  |  105 ---
 emacs/guix-ui.el                    |  323 ----------
 emacs/guix-utils.el                 |  609 ------------------
 emacs/local.mk                      |   77 ---
 gnu/packages/package-management.scm |    6 +-
 44 files changed, 12 insertions(+), 12012 deletions(-)
 delete mode 100644 doc/emacs.texi
 delete mode 100644 emacs/guix-about.el
 delete mode 100644 emacs/guix-backend.el
 delete mode 100644 emacs/guix-base.el
 delete mode 100644 emacs/guix-buffer.el
 delete mode 100644 emacs/guix-build-log.el
 delete mode 100644 emacs/guix-command.el
 delete mode 100644 emacs/guix-config.el.in
 delete mode 100644 emacs/guix-devel.el
 delete mode 100644 emacs/guix-entry.el
 delete mode 100644 emacs/guix-external.el
 delete mode 100644 emacs/guix-geiser.el
 delete mode 100644 emacs/guix-guile.el
 delete mode 100644 emacs/guix-help-vars.el
 delete mode 100644 emacs/guix-helper.scm.in
 delete mode 100644 emacs/guix-history.el
 delete mode 100644 emacs/guix-hydra-build.el
 delete mode 100644 emacs/guix-hydra-jobset.el
 delete mode 100644 emacs/guix-hydra.el
 delete mode 100644 emacs/guix-info.el
 delete mode 100644 emacs/guix-init.el
 delete mode 100644 emacs/guix-license.el
 delete mode 100644 emacs/guix-list.el
 delete mode 100644 emacs/guix-location.el
 delete mode 100644 emacs/guix-main.scm
 delete mode 100644 emacs/guix-messages.el
 delete mode 100644 emacs/guix-pcomplete.el
 delete mode 100644 emacs/guix-popup.el
 delete mode 100644 emacs/guix-prettify.el
 delete mode 100644 emacs/guix-profiles.el
 delete mode 100644 emacs/guix-read.el
 delete mode 100644 emacs/guix-ui-generation.el
 delete mode 100644 emacs/guix-ui-license.el
 delete mode 100644 emacs/guix-ui-location.el
 delete mode 100644 emacs/guix-ui-package.el
 delete mode 100644 emacs/guix-ui-system-generation.el
 delete mode 100644 emacs/guix-ui.el
 delete mode 100644 emacs/guix-utils.el
 delete mode 100644 emacs/local.mk

diff --git a/Makefile.am b/Makefile.am
index 6cc3114..15939af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -465,10 +465,6 @@ AM_DISTCHECK_CONFIGURE_FLAGS =			\
   --with-nix-prefix="$(NIX_PREFIX)"		\
   --enable-daemon
 
-dist_emacsui_DATA = emacs/guix-main.scm
-nodist_emacsui_DATA = emacs/guix-helper.scm
-include emacs/local.mk
-
 # The self-contained tarball.
 guix-binary.%.tar.xz:
 	$(AM_V_GEN)GUIX_PACKAGE_PATH= \
@@ -548,10 +544,6 @@ AM_V_DOT = $(AM_V_DOT_$(V))
 AM_V_DOT_ = $(AM_V_DOT_$(AM_DEFAULT_VERBOSITY))
 AM_V_DOT_0 = @echo "  DOT     " $@;
 
-AM_V_EMACS = $(AM_V_EMACS_$(V))
-AM_V_EMACS_ = $(AM_V_EMACS_$(AM_DEFAULT_VERBOSITY))
-AM_V_EMACS_0 = @echo "  EMACS   " $@;
-
 AM_V_HELP2MAN = $(AM_V_HELP2MAN_$(V))
 AM_V_HELP2MAN_ = $(AM_V_HELP2MAN_$(AM_DEFAULT_VERBOSITY))
 AM_V_HELP2MAN_0 = @echo "  HELP2MAN" $@;
diff --git a/configure.ac b/configure.ac
index 4888624..c3173d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -237,14 +237,4 @@ AC_CONFIG_FILES([test-env:build-aux/test-env.in], [chmod +x test-env])
 AC_CONFIG_FILES([pre-inst-env:build-aux/pre-inst-env.in],
   [chmod +x pre-inst-env])
 
-dnl Emacs interface.
-AC_PATH_PROG([DOT_USER_PROGRAM], [dot], [dot])
-AM_PATH_LISPDIR
-AM_CONDITIONAL([HAVE_EMACS], [test "x$EMACS" != "xno"])
-
-emacsuidir="${guilemoduledir}/guix/emacs"
-AC_SUBST([emacsuidir])
-AC_CONFIG_FILES([emacs/guix-config.el
-                 emacs/guix-helper.scm])
-
 AC_OUTPUT
diff --git a/doc/contributing.texi b/doc/contributing.texi
index de08f9b..24db9a8 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -187,9 +187,6 @@ facilities to directly operate on the syntax tree, such as raising an
 s-expression or wrapping it, swallowing or rejecting the following
 s-expression, etc.
 
-GNU Guix also comes with a minor mode that provides some additional
-functionality for Scheme buffers (@pxref{Emacs Development}).
-
 
 @node Coding Style
 @section Coding Style
diff --git a/doc/emacs.texi b/doc/emacs.texi
deleted file mode 100644
index 1ffb9f6..0000000
--- a/doc/emacs.texi
+++ /dev/null
@@ -1,881 +0,0 @@
-@node Emacs Interface
-@chapter Emacs Interface
-
-@cindex Emacs
-GNU Guix comes with several useful modules (known as ``guix.el'') for
-GNU@tie{}Emacs which are intended to make an Emacs user interaction with
-Guix convenient and fun.
-
-@menu
-* Initial Setup: Emacs Initial Setup.	Preparing @file{~/.emacs}.
-* Package Management: Emacs Package Management.	Managing packages and generations.
-* Licenses: Emacs Licenses.		Interface for licenses of Guix packages.
-* Package Source Locations: Emacs Package Locations.	Interface for package location files.
-* Popup Interface: Emacs Popup Interface.	Magit-like interface for guix commands.
-* Prettify Mode: Emacs Prettify.	Abbreviating @file{/gnu/store/@dots{}} file names.
-* Build Log Mode: Emacs Build Log.	Highlighting Guix build logs.
-* Completions: Emacs Completions.	Completing @command{guix} shell command.
-* Development: Emacs Development.	Tools for Guix developers.
-* Hydra: Emacs Hydra.			Interface for Guix build farm.
-@end menu
-
-
-@node Emacs Initial Setup
-@section Initial Setup
-
-On the Guix System Distribution (@pxref{GNU Distribution}), ``guix.el''
-is ready to use, provided Guix is installed system-wide, which is the
-case by default.  So if that is what you're using, you can happily skip
-this section and read about the fun stuff.
-
-If you're not yet a happy user of GuixSD, a little bit of setup is needed.
-To be able to use ``guix.el'', you need to install the following
-packages:
-
-@itemize
-@item
-@uref{http://www.gnu.org/software/emacs/, GNU Emacs}, version 24.3 or
-later;
-
-@item
-@uref{http://nongnu.org/geiser/, Geiser}, version 0.3 or later: it is
-used for interacting with the Guile process.
-
-@item
-@uref{https://github.com/magit/magit/, magit-popup library}.  You
-already have this library if you use Magit 2.1.0 or later.  This library
-is an optional dependency---it is required only for @kbd{M-x@tie{}guix}
-command (@pxref{Emacs Popup Interface}).
-
-@end itemize
-
-When it is done, ``guix.el'' may be configured by requiring
-@code{guix-autoloads} file.  If you install Guix in your user profile,
-this auto-loading is done automatically by our Emacs package
-(@pxref{Application Setup}), so a universal recipe for configuring
-``guix.el'' is: @command{guix package -i guix}.  If you do this, there
-is no need to read further.
-
-For the manual installation, you need to add the following code into
-your init file (@pxref{Init File,,, emacs, The GNU Emacs Manual}):
-
-@example
-(add-to-list 'load-path "/path/to/directory-with-guix.el")
-(require 'guix-autoloads nil t)
-@end example
-
-So the only thing you need to figure out is where the directory with
-elisp files for Guix is placed.  It depends on how you installed Guix:
-
-@itemize
-@item
-If it was installed by a package manager of your distribution or by a
-usual @code{./configure && make && make install} command sequence, then
-elisp files are placed in a standard directory with Emacs packages
-(usually it is @file{/usr/share/emacs/site-lisp/}), which is already in
-@code{load-path}, so there is no need to add that directory there.  Note
-that if you don't update this installation periodically, you may get an
-outdated Emacs code which does not work with the current Guile code of
-Guix.
-
-@item
-If you used a binary installation method (@pxref{Binary Installation}),
-then Guix is installed somewhere in the store, so the elisp files are
-placed in @file{/gnu/store/@dots{}-guix-0.8.2/share/emacs/site-lisp/} or
-alike.  However it is not recommended to refer directly to a store
-directory, as it may be garbage-collected one day.  So a better choice
-would be to install Guix using Guix itself with @command{guix package -i
-guix}.
-
-@item
-If you did not install Guix at all and prefer a hacking way
-(@pxref{Running Guix Before It Is Installed}), along with augmenting
-@code{load-path} you need to set @code{guix-load-path} variable to the
-same directory, so your final configuration will look like this:
-
-@example
-(let ((dir "/path/to/your-guix-git-tree/emacs"))
-  (add-to-list 'load-path dir)
-  (setq guix-load-path dir))
-(require 'guix-autoloads nil t)
-@end example
-@end itemize
-
-
-@node Emacs Package Management
-@section Package Management
-
-Once ``guix.el'' has been successfully configured, you should be able to
-use a visual interface for routine package management tasks, pretty much
-like the @command{guix package} command (@pxref{Invoking guix package}).
-Specifically, it makes it easy to:
-
-@itemize
-@item browse and display packages and generations;
-@item search, install, upgrade and remove packages;
-@item display packages from previous generations;
-@item do some other useful things.
-@end itemize
-
-@menu
-* Commands: Emacs Commands.			@kbd{M-x guix-@dots{}}
-* General information: Emacs General info.	Common for both interfaces.
-* ``List'' buffer: Emacs List buffer.		List-like interface.
-* ``Info'' buffer: Emacs Info buffer.		Help-like interface.
-* Configuration: Emacs Configuration.		Configuring the interface.
-@end menu
-
-@node Emacs Commands
-@subsection Commands
-
-All commands for displaying packages and generations use the current
-profile, which can be changed with
-@kbd{M-x@tie{}guix-set-current-profile}.  Alternatively, if you call any
-of these commands with prefix argument (@kbd{C-u}), you will be prompted
-for a profile just for that command.
-
-Commands for displaying packages:
-
-@table @kbd
-
-@item M-x guix-all-available-packages
-@itemx M-x guix-newest-available-packages
-Display all/newest available packages.
-
-@item M-x guix-installed-packages
-@itemx M-x guix-installed-user-packages
-@itemx M-x guix-installed-system-packages
-Display installed packages.  As described above, @kbd{M-x
-guix-installed-packages} uses an arbitrary profile that you can specify,
-while the other commands display packages installed in 2 special
-profiles: @file{~/.guix-profile} and @file{/run/current-system/profile}
-(only on GuixSD).
-
-@item M-x guix-obsolete-packages
-Display obsolete packages (the packages that are installed in a profile
-but cannot be found among available packages).
-
-@item M-x guix-packages-by-name
-Display package(s) with the specified name.
-
-@item M-x guix-packages-by-license
-Display package(s) with the specified license.
-
-@item M-x guix-packages-by-location
-Display package(s) located in the specified file.  These files usually
-have the following form: @file{gnu/packages/emacs.scm}, but don't type
-them manually!  Press @key{TAB} to complete the file name.
-
-@item M-x guix-package-from-file
-Display package that the code within the specified file evaluates to.
-@xref{Invoking guix package, @code{--install-from-file}}, for an example
-of what such a file may look like.
-
-@item M-x guix-search-by-regexp
-Search for packages by a specified regexp.  By default ``name'',
-``synopsis'' and ``description'' of the packages will be searched.  This
-can be changed by modifying @code{guix-package-search-params} variable.
-
-@item M-x guix-search-by-name
-Search for packages with names matching a specified regexp.  This
-command is the same as @code{guix-search-by-regexp}, except only a
-package ``name'' is searched.
-
-@end table
-
-By default, these commands display each output on a separate line.  If
-you prefer to see a list of packages---i.e., a list with a package per
-line, use the following setting:
-
-@example
-(setq guix-package-list-type 'package)
-@end example
-
-Commands for displaying generations:
-
-@table @kbd
-
-@item M-x guix-generations
-List all the generations.
-
-@item M-x guix-last-generations
-List the @var{N} last generations.  You will be prompted for the number
-of generations.
-
-@item M-x guix-generations-by-time
-List generations matching time period.  You will be prompted for the
-period using Org mode time prompt based on Emacs calendar (@pxref{The
-date/time prompt,,, org, The Org Manual}).
-
-@end table
-
-Analogously on GuixSD you can also display system generations:
-
-@table @kbd
-@item M-x guix-system-generations
-@item M-x guix-last-system-generations
-@item M-x guix-system-generations-by-time
-@end table
-
-You can also invoke the @command{guix pull} command (@pxref{Invoking
-guix pull}) from Emacs using:
-
-@table @kbd
-@item M-x guix-pull
-With @kbd{C-u}, make it verbose.
-@end table
-
-Once @command{guix pull} has succeeded, the Guix REPL is restarted.  This
-allows you to keep using the Emacs interface with the updated Guix.
-
-
-@node Emacs General info
-@subsection General information
-
-The following keys are available for both ``list'' and ``info'' types of
-buffers:
-
-@table @kbd
-@item l
-@itemx r
-Go backward/forward by the history of the displayed results (this
-history is similar to the history of the Emacs @code{help-mode} or
-@code{Info-mode}).
-
-@item g
-Revert current buffer: update information about the displayed
-packages/generations and redisplay it.
-
-@item R
-Redisplay current buffer (without updating information).
-
-@item M
-Apply manifest to the current profile or to a specified profile, if
-prefix argument is used.  This has the same meaning as @code{--manifest}
-option (@pxref{Invoking guix package}).
-
-@item C-c C-z
-@cindex REPL
-@cindex read-eval-print loop
-Go to the Guix REPL (@pxref{The REPL,,, geiser, Geiser User Manual}).
-
-@item h
-@itemx ?
-Describe current mode to see all available bindings.
-
-@end table
-
-@emph{Hint:} If you need several ``list'' or ``info'' buffers, you can
-simply @kbd{M-x clone-buffer} them, and each buffer will have its own
-history.
-
-@emph{Warning:} Name/version pairs cannot be used to identify packages
-(because a name is not necessarily unique), so ``guix.el'' uses special
-identifiers that live only during a guile session, so if the Guix REPL
-was restarted, you may want to revert ``list'' buffer (by pressing
-@kbd{g}).
-
-@node Emacs List buffer
-@subsection ``List'' buffer
-
-An interface of a ``list'' buffer is similar to the interface provided
-by ``package.el'' (@pxref{Package Menu,,, emacs, The GNU Emacs Manual}).
-
-Default key bindings available for both ``package-list'' and
-``generation-list'' buffers:
-
-@table @kbd
-@item m
-Mark the current entry (with prefix, mark all entries).
-@item u
-Unmark the current entry (with prefix, unmark all entries).
-@item @key{DEL}
-Unmark backward.
-@item S
-Sort entries by a specified column.
-@end table
-
-A ``package-list'' buffer additionally provides the following bindings:
-
-@table @kbd
-@item @key{RET}
-Describe marked packages (display available information in a
-``package-info'' buffer).
-@item i
-Mark the current package for installation.
-@item d
-Mark the current package for deletion.
-@item U
-Mark the current package for upgrading.
-@item ^
-Mark all obsolete packages for upgrading.
-@item e
-Edit the definition of the current package (go to its location).  This is
-similar to @command{guix edit} command (@pxref{Invoking guix edit}), but
-for opening a package recipe in the current Emacs instance.
-@item x
-Execute actions on the marked packages.
-@item B
-Display latest builds of the current package (@pxref{Emacs Hydra}).
-@end table
-
-A ``generation-list'' buffer additionally provides the following
-bindings:
-
-@table @kbd
-@item @key{RET}
-List packages installed in the current generation.
-@item i
-Describe marked generations (display available information in a
-``generation-info'' buffer).
-@item s
-Switch profile to the current generation.
-@item d
-Mark the current generation for deletion (with prefix, mark all
-generations).
-@item x
-Execute actions on the marked generations---i.e., delete generations.
-@item e
-Run Ediff (@pxref{Top,,, ediff, The Ediff Manual}) on package outputs
-installed in the 2 marked generations.  With prefix argument, run Ediff
-on manifests of the marked generations.
-@item D
-@itemx =
-Run Diff (@pxref{Diff Mode,,, emacs, The GNU Emacs Manual}) on package
-outputs installed in the 2 marked generations.  With prefix argument,
-run Diff on manifests of the marked generations.
-@item +
-List package outputs added to the latest marked generation comparing
-with another marked generation.
-@item -
-List package outputs removed from the latest marked generation comparing
-with another marked generation.
-@end table
-
-@node Emacs Info buffer
-@subsection ``Info'' buffer
-
-The interface of an ``info'' buffer is similar to the interface of
-@code{help-mode} (@pxref{Help Mode,,, emacs, The GNU Emacs Manual}).
-
-``Info'' buffer contains some buttons (as usual you may use @key{TAB} /
-@kbd{S-@key{TAB}} to move between buttons---@pxref{Mouse References,,,
-emacs, The GNU Emacs Manual}) which can be used to:
-
-@itemize @bullet
-@item (in a ``package-info'' buffer)
-
-@itemize @minus
-@item install/remove a package;
-@item jump to a package location;
-@item browse home page of a package;
-@item browse license URL;
-@item describe packages from ``Inputs'' fields.
-@end itemize
-
-@item (in a ``generation-info'' buffer)
-
-@itemize @minus
-@item remove a generation;
-@item switch to a generation;
-@item list packages installed in a generation;
-@item jump to a generation directory.
-@end itemize
-
-@end itemize
-
-It is also possible to copy a button label (a link to an URL or a file)
-by pressing @kbd{c} on a button.
-
-
-@node Emacs Configuration
-@subsection Configuration
-
-There are many variables you can modify to change the appearance or
-behavior of Emacs user interface.  Some of these variables are described
-in this section.  Also you can use Custom Interface (@pxref{Easy
-Customization,,, emacs, The GNU Emacs Manual}) to explore/set variables
-(not all) and faces.
-
-@menu
-* Guile and Build Options: Emacs Build Options.	Specifying how packages are built.
-* Buffer Names: Emacs Buffer Names.	Names of Guix buffers.
-* Keymaps: Emacs Keymaps.		Configuring key bindings.
-* Appearance: Emacs Appearance.		Settings for visual appearance.
-@end menu
-
-@node Emacs Build Options
-@subsubsection Guile and Build Options
-
-@table @code
-@item guix-guile-program
-If you have some special needs for starting a Guile process, you may set
-this variable, for example:
-
-@example
-(setq guix-guile-program '("/bin/guile" "--no-auto-compile"))
-@end example
-
-@item guix-use-substitutes
-If nil, has the same meaning as @code{--no-substitutes} option
-(@pxref{Invoking guix build}).
-
-@item guix-dry-run
-If non-nil, has the same meaning as @code{--dry-run} option
-(@pxref{Invoking guix build}).
-
-@end table
-
-@node Emacs Buffer Names
-@subsubsection Buffer Names
-
-Default names of ``guix.el'' buffers (``*Guix@tie{}@dots{}*'') may be
-changed with the following variables:
-
-@table @code
-@item guix-package-list-buffer-name
-@item guix-output-list-buffer-name
-@item guix-generation-list-buffer-name
-@item guix-package-info-buffer-name
-@item guix-output-info-buffer-name
-@item guix-generation-info-buffer-name
-@item guix-repl-buffer-name
-@item guix-internal-repl-buffer-name
-@end table
-
-By default, the name of a profile is also displayed in a ``list'' or
-``info'' buffer name.  To change this behavior, use
-@code{guix-ui-buffer-name-function} variable.
-
-For example, if you want to display all types of results in a single
-buffer (in such case you will probably use a history (@kbd{l}/@kbd{r})
-extensively), you may do it like this:
-
-@example
-(let ((name "Guix Universal"))
-  (setq
-   guix-package-list-buffer-name    name
-   guix-output-list-buffer-name     name
-   guix-generation-list-buffer-name name
-   guix-package-info-buffer-name    name
-   guix-output-info-buffer-name     name
-   guix-generation-info-buffer-name name))
-@end example
-
-@node Emacs Keymaps
-@subsubsection Keymaps
-
-If you want to change default key bindings, use the following keymaps
-(@pxref{Init Rebinding,,, emacs, The GNU Emacs Manual}):
-
-@table @code
-@item guix-buffer-map
-Parent keymap with general keys for any buffer type.
-
-@item guix-ui-map
-Parent keymap with general keys for buffers used for Guix package
-management (for packages, outputs and generations).
-
-@item guix-list-mode-map
-Parent keymap with general keys for ``list'' buffers.
-
-@item guix-package-list-mode-map
-Keymap with specific keys for ``package-list'' buffers.
-
-@item guix-output-list-mode-map
-Keymap with specific keys for ``output-list'' buffers.
-
-@item guix-generation-list-mode-map
-Keymap with specific keys for ``generation-list'' buffers.
-
-@item guix-info-mode-map
-Parent keymap with general keys for ``info'' buffers.
-
-@item guix-package-info-mode-map
-Keymap with specific keys for ``package-info'' buffers.
-
-@item guix-output-info-mode-map
-Keymap with specific keys for ``output-info'' buffers.
-
-@item guix-generation-info-mode-map
-Keymap with specific keys for ``generation-info'' buffers.
-
-@item guix-info-button-map
-Keymap with keys available when a point is placed on a button.
-
-@end table
-
-@node Emacs Appearance
-@subsubsection Appearance
-
-You can change almost any aspect of ``list'' / ``info'' buffers using
-the following variables (@dfn{ENTRY-TYPE} means @code{package},
-@code{output} or @code{generation}):
-
-@table @code
-@item guix-ENTRY-TYPE-list-format
-@itemx guix-ENTRY-TYPE-list-titles
-Specify the columns, their names, what and how is displayed in ``list''
-buffers.
-
-@item guix-ENTRY-TYPE-info-format
-@itemx guix-ENTRY-TYPE-info-titles
-@itemx guix-info-ignore-empty-values
-@itemx guix-info-param-title-format
-@itemx guix-info-multiline-prefix
-@itemx guix-info-indent
-@itemx guix-info-fill
-@itemx guix-info-delimiter
-Various settings for ``info'' buffers.
-
-@end table
-
-
-@node Emacs Licenses
-@section Licenses
-
-If you want to browse the URL of a particular license, or to look at a
-list of licenses, you may use the following commands:
-
-@table @kbd
-
-@item M-x guix-browse-license-url
-Choose a license from a completion list to browse its URL using
-@code{browse-url} function (@pxref{Browse-URL,,, emacs, The GNU Emacs
-Manual}).
-
-@item M-x guix-licenses
-Display a list of available licenses.  You can press @kbd{@key{RET}}
-there to display packages with this license in the same way as @kbd{M-x
-guix-packages-by-license} would do (@pxref{Emacs Commands}).
-
-@item M-x guix-find-license-definition
-Open @file{@dots{}/guix/licenses.scm} and move to the specified license.
-
-@end table
-
-
-@node Emacs Package Locations
-@section Package Source Locations
-
-As you know, package definitions are placed in Guile files, also known
-as @dfn{package locations}.  The following commands should help you not
-get lost in these locations:
-
-@table @kbd
-
-@item M-x guix-locations
-Display a list of package locations.  You can press @key{RET} there to
-display packages placed in the current location in the same way as
-@kbd{M-x guix-packages-by-location} would do (@pxref{Emacs Commands}).
-Note that when the point is on a location button, @key{RET} will open
-this location file.
-
-@item M-x guix-find-location
-Open the given package definition source file (press @key{TAB} to choose
-a location from a completion list).
-
-@item M-x guix-edit
-Find location of a specified package.  This is an Emacs analog of
-@command{guix edit} command (@pxref{Invoking guix edit}).  As with
-@kbd{M-x guix-packages-by-name}, you can press @key{TAB} to complete a
-package name.
-
-@end table
-
-If you are contributing to Guix, you may find it useful for @kbd{M-x
-guix-find-location} and @kbd{M-x guix-edit} to open locations from your
-Git checkout.  This can be done by setting @code{guix-directory}
-variable.  For example, after this:
-
-@example
-(setq guix-directory "~/src/guix")
-@end example
-
-@kbd{M-x guix-edit guix} opens
-@file{~/src/guix/gnu/packages/package-management.scm} file.
-
-Also you can use @kbd{C-u} prefix argument to specify a directory just
-for the current @kbd{M-x guix-find-location} or @kbd{M-x guix-edit}
-command.
-
-
-@node Emacs Popup Interface
-@section Popup Interface
-
-If you ever used Magit, you know what ``popup interface'' is
-(@pxref{Top,,, magit-popup, Magit-Popup User Manual}).  Even if you are
-not acquainted with Magit, there should be no worries as it is very
-intuitive.
-
-So @kbd{M-x@tie{}guix} command provides a top-level popup interface for
-all available guix commands.  When you select an option, you'll be
-prompted for a value in the minibuffer.  Many values have completions,
-so don't hesitate to press @key{TAB} key.  Multiple values (for example,
-packages or lint checkers) should be separated by commas.
-
-After specifying all options and switches for a command, you may choose
-one of the available actions.  The following default actions are
-available for all commands:
-
-@itemize
-
-@item
-Run the command in the Guix REPL.  It is faster than running
-@code{guix@tie{}@dots{}} command directly in shell, as there is no
-need to run another guile process and to load required modules there.
-
-@item
-Run the command in a shell buffer.  You can set
-@code{guix-run-in-shell-function} variable to fine tune the shell buffer
-you want to use.
-
-@item
-Add the command line to the kill ring (@pxref{Kill Ring,,, emacs, The
-GNU Emacs Manual}).
-
-@end itemize
-
-Several commands (@command{guix graph}, @command{guix system shepherd-graph}
-and @command{guix system extension-graph}) also have a ``View graph''
-action, which allows you to view a generated graph using @command{dot}
-command (specified by @code{guix-dot-program} variable).  By default a
-PNG file will be saved in @file{/tmp} directory and will be opened
-directly in Emacs.  This behavior may be changed with the following
-variables:
-
-@table @code
-
-@item guix-find-file-function
-Function used to open a generated graph.  If you want to open a graph in
-an external program, you can do it by modifying this variable---for
-example, you can use a functionality provided by the Org Mode
-(@pxref{Top,,, org, The Org Manual}):
-
-@example
-(setq guix-find-file-function 'org-open-file)
-(add-to-list 'org-file-apps '("\\.png\\'" . "sxiv %s"))
-@end example
-
-@item guix-dot-default-arguments
-Command line arguments to run @command{dot} command.  If you change an
-output format (for example, into @code{-Tpdf}), you also need to change
-the next variable.
-
-@item guix-dot-file-name-function
-Function used to define a name of the generated graph file.  Default
-name is @file{/tmp/guix-emacs-graph-XXXXXX.png}.
-
-@end table
-
-So, for example, if you want to generate and open a PDF file in your
-Emacs, you may change the settings like this:
-
-@example
-(defun my-guix-pdf-graph ()
-  "/tmp/my-current-guix-graph.pdf")
-
-(setq guix-dot-default-arguments '("-Tpdf")
-      guix-dot-file-name-function 'my-guix-pdf-graph)
-@end example
-
-
-@node Emacs Prettify
-@section Guix Prettify Mode
-
-GNU@tie{}Guix also comes with ``guix-prettify.el''.  It provides a minor
-mode for abbreviating store file names by replacing hash sequences of
-symbols with ``@dots{}'':
-
-@example
-/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1
-@result{} /gnu/store/…-foo-0.1
-@end example
-
-Once you set up ``guix.el'' (@pxref{Emacs Initial Setup}), the following
-commands become available:
-
-@table @kbd
-
-@item M-x guix-prettify-mode
-Enable/disable prettifying for the current buffer.
-
-@item M-x global-guix-prettify-mode
-Enable/disable prettifying globally.
-
-@end table
-
-To automatically enable @code{guix-prettify-mode} globally on Emacs
-start, add the following line to your init file:
-
-@example
-(global-guix-prettify-mode)
-@end example
-
-If you want to enable it only for specific major modes, add it to the
-mode hooks (@pxref{Hooks,,, emacs, The GNU Emacs Manual}), for example:
-
-@example
-(add-hook 'shell-mode-hook 'guix-prettify-mode)
-(add-hook 'dired-mode-hook 'guix-prettify-mode)
-@end example
-
-
-@node Emacs Build Log
-@section Build Log Mode
-
-GNU@tie{}Guix provides major and minor modes for highlighting build
-logs.  So when you have a file with a package build output---for
-example, a file returned by @command{guix build --log-file @dots{}}
-command (@pxref{Invoking guix build}), you may call @kbd{M-x
-guix-build-log-mode} command in the buffer with this file.  This major
-mode highlights some lines specific to build output and provides the
-following key bindings:
-
-@table @kbd
-
-@item M-n
-Move to the next build phase.
-
-@item M-p
-Move to the previous build phase.
-
-@item @key{TAB}
-Toggle (show/hide) the body of the current build phase.
-
-@item S-@key{TAB}
-Toggle (show/hide) the bodies of all build phases.
-
-@end table
-
-There is also @kbd{M-x guix-build-log-minor-mode} which also provides
-the same highlighting and the same key bindings as the major mode, but
-prefixed with @kbd{C-c}.  By default, this minor mode is enabled in
-shell buffers (@pxref{Interactive Shell,,, emacs, The GNU Emacs
-Manual}).  If you don't like it, set
-@code{guix-build-log-minor-mode-activate} to nil.
-
-
-@node Emacs Completions
-@section Shell Completions
-
-Another feature that becomes available after configuring Emacs interface
-(@pxref{Emacs Initial Setup}) is completing of @command{guix}
-subcommands, options, packages and other things in @code{shell}
-(@pxref{Interactive Shell,,, emacs, The GNU Emacs Manual}) and
-@code{eshell} (@pxref{Top,,, eshell, Eshell: The Emacs Shell}).
-
-It works the same way as other completions do.  Just press @key{TAB}
-when your intuition tells you.
-
-And here are some examples, where pressing @key{TAB} may complete
-something:
-
-@itemize @w{}
-
-@item @code{guix pa}@key{TAB}
-@item @code{guix package -}@key{TAB}
-@item @code{guix package --}@key{TAB}
-@item @code{guix package -i gei}@key{TAB}
-@item @code{guix build -L/tm}@key{TAB}
-@item @code{guix build --sy}@key{TAB}
-@item @code{guix build --system=i}@key{TAB}
-@item @code{guix system rec}@key{TAB}
-@item @code{guix lint --checkers=sy}@key{TAB}
-@item @code{guix lint --checkers=synopsis,des}@key{TAB}
-
-@end itemize
-
-
-@node Emacs Development
-@section Development
-
-By default, when you open a Scheme file, @code{guix-devel-mode} will be
-activated (if you don't want it, set @code{guix-devel-activate-mode} to
-nil).  This minor mode provides the following key bindings:
-
-@table @kbd
-
-@item C-c . k
-Copy the name of the current Guile module into kill ring
-(@code{guix-devel-copy-module-as-kill}).
-
-@item C-c . u
-Use the current Guile module.  Often after opening a Scheme file, you
-want to use a module it defines, so you switch to the Geiser REPL and
-write @code{,use (some module)} there.  You may just use this command
-instead (@code{guix-devel-use-module}).
-
-@item C-c . b
-Build a package defined by the current variable definition.  The
-building process is run in the current Geiser REPL.  If you modified the
-current package definition, don't forget to reevaluate it before calling
-this command---for example, with @kbd{C-M-x} (@pxref{To eval or not to
-eval,,, geiser, Geiser User Manual})
-(@code{guix-devel-build-package-definition}).
-
-@item C-c . s
-Build a source derivation of the package defined by the current variable
-definition.  This command has the same meaning as @code{guix build -S}
-shell command (@pxref{Invoking guix build})
-(@code{guix-devel-build-package-source}).
-
-@item C-c . l
-Lint (check) a package defined by the current variable definition
-(@pxref{Invoking guix lint}) (@code{guix-devel-lint-package}).
-
-@end table
-
-Unluckily, there is a limitation related to long-running REPL commands.
-When there is a running process in a Geiser REPL, you are not supposed
-to evaluate anything in a scheme buffer, because this will ``freeze''
-the REPL: it will stop producing any output (however, the evaluating
-process will continue---you will just not see any progress anymore).  Be
-aware: even moving the point in a scheme buffer may ``break'' the REPL
-if Autodoc (@pxref{Autodoc and friends,,, geiser, Geiser User Manual})
-is enabled (which is the default).
-
-So you have to postpone editing your scheme buffers until the running
-evaluation will be finished in the REPL.
-
-Alternatively, to avoid this limitation, you may just run another Geiser
-REPL, and while something is being evaluated in the previous REPL, you
-can continue editing a scheme file with the help of the current one.
-
-
-@node Emacs Hydra
-@section Hydra
-
-The continuous integration server at @code{hydra.gnu.org} builds all
-the distribution packages on the supported architectures and serves
-them as substitutes (@pxref{Substitutes}).  Continuous integration is
-currently orchestrated by @uref{https://nixos.org/hydra/, Hydra}.
-
-This section describes an Emacs interface to query Hydra to know the
-build status of specific packages, discover recent and ongoing builds,
-view build logs, and so on.  This interface is mostly the same as the
-``list''/``info'' interface for displaying packages and generations
-(@pxref{Emacs Package Management}).
-
-The following commands are available:
-
-@table @kbd
-
-@item M-x guix-hydra-latest-builds
-Display latest failed or successful builds (you will be prompted for a
-number of builds).  With @kbd{C-u}, you will also be prompted for other
-parameters (project, jobset, job and system).
-
-@item M-x guix-hydra-queued-builds
-Display scheduled or currently running builds (you will be prompted for
-a number of builds).
-
-@item M-x guix-hydra-jobsets
-Display available jobsets (you will be prompted for a project).
-
-@end table
-
-In a list of builds you can press @kbd{L} key to display a build log of
-the current build.  Also both a list of builds and a list of jobsets
-provide @kbd{B} key to display latest builds of the current job or
-jobset (don't forget about @kbd{C-u}).
diff --git a/doc/guix.texi b/doc/guix.texi
index 69129d5..8756061 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -54,12 +54,6 @@ Documentation License''.
 * guix environment: (guix)Invoking guix environment. Building development environments with Guix.
 @end direntry
 
-@dircategory Emacs
-@direntry
-* Guix user interface: (guix)Emacs Interface. Package management from the comfort of Emacs.
-@end direntry
-
-
 @titlepage
 @title GNU Guix Reference Manual
 @subtitle Using the GNU Guix Functional Package Manager
@@ -86,7 +80,6 @@ package management tool written for the GNU system.
 * Introduction::                What is Guix about?
 * Installation::                Installing Guix.
 * Package Management::          Package installation, upgrade, etc.
-* Emacs Interface::             Using Guix from Emacs.
 * Programming Interface::       Using Guix in Scheme.
 * Utilities::                   Package management commands.
 * GNU Distribution::            Software for your friendly GNU system.
@@ -124,19 +117,6 @@ Package Management
 * Invoking guix pull::          Fetching the latest Guix and distribution.
 * Invoking guix archive::       Exporting and importing store files.
 
-Emacs Interface
-
-* Initial Setup: Emacs Initial Setup.	Preparing @file{~/.emacs}.
-* Package Management: Emacs Package Management.	Managing packages and generations.
-* Licenses: Emacs Licenses.		Interface for licenses of Guix packages.
-* Package Source Locations: Emacs Package Locations.	Interface for package location files.
-* Popup Interface: Emacs Popup Interface.	Magit-like interface for guix commands.
-* Prettify Mode: Emacs Prettify.	Abbreviating @file{/gnu/store/@dots{}} file names.
-* Build Log Mode: Emacs Build Log.	Highlighting Guix build logs.
-* Completions: Emacs Completions.	Completing @command{guix} shell command.
-* Development: Emacs Development.	Tools for Guix developers.
-* Hydra: Emacs Hydra.			Interface for Guix build farm.
-
 Programming Interface
 
 * Defining Packages::           Defining new packages.
@@ -278,8 +258,7 @@ assists with the creation and maintenance of software environments.
 @cindex user interfaces
 Guix provides a command-line package management interface
 (@pxref{Invoking guix package}), a set of command-line utilities
-(@pxref{Utilities}), a visual user interface in Emacs (@pxref{Emacs
-Interface}), as well as Scheme programming interfaces
+(@pxref{Utilities}), as well as Scheme programming interfaces
 (@pxref{Programming Interface}).
 @cindex build daemon
 Its @dfn{build daemon} is responsible for building packages on behalf of
@@ -1414,10 +1393,14 @@ procedures or dependencies.  Guix also goes beyond this obvious set of
 features.
 
 This chapter describes the main features of Guix, as well as the package
-management tools it provides.  Two user interfaces are provided for
-routine package management tasks: A command-line interface described below
-(@pxref{Invoking guix package, @code{guix package}}), as well as a visual user
-interface in Emacs described in a subsequent chapter (@pxref{Emacs Interface}).
+management tools it provides.  Along with the command-line interface
+described below (@pxref{Invoking guix package, @code{guix package}}),
+you may also use Emacs Interface, after installing @code{emacs-guix}
+package (run @kbd{M-x guix-help} command to start with it):
+
+@example
+guix package -i emacs-guix
+@end example
 
 @menu
 * Features::                    How Guix will make your life brighter.
@@ -1434,9 +1417,7 @@ interface in Emacs described in a subsequent chapter (@pxref{Emacs Interface}).
 
 When using Guix, each package ends up in the @dfn{package store}, in its
 own directory---something that resembles
-@file{/gnu/store/xxx-package-1.2}, where @code{xxx} is a base32 string
-(note that Guix comes with an Emacs extension to shorten those file
-names, @pxref{Emacs Prettify}.)
+@file{/gnu/store/xxx-package-1.2}, where @code{xxx} is a base32 string.
 
 Instead of referring to these directories, users have their own
 @dfn{profile}, which points to the packages that they actually want to
@@ -1982,9 +1963,7 @@ also result from derivation builds, can be available as substitutes.
 
 The @code{hydra.gnu.org} server is a front-end to a build farm that
 builds packages from the GNU distribution continuously for some
-architectures, and makes them available as substitutes (@pxref{Emacs
-Hydra}, for information on how to query the continuous integration
-server).  This is the
+architectures, and makes them available as substitutes.  This is the
 default source of substitutes; it can be overridden by passing the
 @option{--substitute-urls} option either to @command{guix-daemon}
 (@pxref{daemon-substitute-urls,, @code{guix-daemon --substitute-urls}})
@@ -2510,9 +2489,6 @@ archive contents coming from possibly untrusted substitute servers.
 @end table
 
 @c *********************************************************************
-@include emacs.texi
-
-@c *********************************************************************
 @node Programming Interface
 @chapter Programming Interface
 
@@ -4923,11 +4899,6 @@ have created your own packages on @code{GUIX_PACKAGE_PATH}
 recipes. Otherwise, you will be able to examine the read-only recipes
 for packages currently in the store.
 
-If you are using Emacs, note that the Emacs user interface provides the
-@kbd{M-x guix-edit} command and a similar functionality in the ``package
-info'' and ``package list'' buffers created by the @kbd{M-x
-guix-search-by-name} and similar commands (@pxref{Emacs Commands}).
-
 
 @node Invoking guix download
 @section Invoking @command{guix download}
diff --git a/emacs/guix-about.el b/emacs/guix-about.el
deleted file mode 100644
index 27a79fe..0000000
--- a/emacs/guix-about.el
+++ /dev/null
@@ -1,37 +0,0 @@
-;;; guix-about.el --- Various info about Guix
-
-;; Copyright © 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public Location as published by
-;; the Free Software Foundation, either version 3 of the Location, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public Location for more details.
-
-;; You should have received a copy of the GNU General Public Location
-;; along with this program.  If not, see <http://www.gnu.org/locations/>.
-
-;;; Commentary:
-
-;; This file provides the code to display various info about Guix (e.g., its
-;; version).
-
-;;; Code:
-
-(require 'guix-config)
-
-;;;###autoload
-(defun guix-version ()
-  "Display Guix version in the echo area."
-  (interactive)
-  (message "%s %s" guix-config-name guix-config-version))
-
-(provide 'guix-about)
-
-;;; guix-about.el ends here
diff --git a/emacs/guix-backend.el b/emacs/guix-backend.el
deleted file mode 100644
index 6341aac..0000000
--- a/emacs/guix-backend.el
+++ /dev/null
@@ -1,393 +0,0 @@
-;;; guix-backend.el --- Making and using Guix REPL
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides the code for interacting with Guile using Guix REPL
-;; (Geiser REPL with some guix-specific additions).
-
-;; By default (if `guix-use-guile-server' is non-nil) 2 Guix REPLs are
-;; started.  The main one (with "guile --listen" process) is used for
-;; "interacting" with a user - for showing a progress of
-;; installing/deleting Guix packages.  The second (internal) REPL is
-;; used for synchronous evaluating, e.g. when information about
-;; packages/generations should be received for a list/info buffer.
-;;
-;; This "2 REPLs concept" makes it possible to have a running process of
-;; installing/deleting packages and to continue to search/list/get info
-;; about other packages at the same time.  If you prefer to use a single
-;; Guix REPL, do not try to receive any information while there is a
-;; running code in the REPL (see
-;; <https://github.com/jaor/geiser/issues/28>).
-;;
-;; Guix REPLs (unlike the usual Geiser REPLs) are not added to
-;; `geiser-repl--repls' variable, and thus cannot be used for evaluating
-;; while editing scm-files.  The only purpose of Guix REPLs is to be an
-;; intermediate between "Guix/Guile level" and "Emacs interface level".
-;; That being said you can still want to use a Guix REPL while hacking
-;; auxiliary scheme-files for "guix.el".  You can just use
-;; `geiser-connect-local' command with `guix-repl-current-socket' to
-;; have a usual Geiser REPL with all stuff defined by "guix.el" package.
-
-;;; Code:
-
-(require 'geiser-mode)
-(require 'geiser-guile)
-(require 'guix-geiser)
-(require 'guix-config)
-(require 'guix-external)
-(require 'guix-emacs)
-(require 'guix-profiles)
-
-(defvar guix-load-path guix-config-emacs-interface-directory
-  "Directory with scheme files for \"guix.el\" package.")
-
-(defvar guix-helper-file
-  (expand-file-name "guix-helper.scm" guix-load-path)
-  "Auxiliary scheme file for loading.")
-
-\f
-;;; REPL
-
-(defgroup guix-repl nil
-  "Settings for Guix REPLs."
-  :prefix "guix-repl-"
-  :group 'guix)
-
-(defcustom guix-repl-startup-time 30000
-  "Time, in milliseconds, to wait for Guix REPL to startup.
-Same as `geiser-repl-startup-time' but is used for Guix REPL.
-If you have a slow system, try to increase this time."
-  :type 'integer
-  :group 'guix-repl)
-
-(defcustom guix-repl-buffer-name "*Guix REPL*"
-  "Default name of a Geiser REPL buffer used for Guix."
-  :type 'string
-  :group 'guix-repl)
-
-(defcustom guix-after-start-repl-hook '(guix-set-directory)
-  "Hook called after Guix REPL is started."
-  :type 'hook
-  :group 'guix-repl)
-
-(defcustom guix-use-guile-server t
-  "If non-nil, start guile with '--listen' argument.
-This allows to receive information about packages using an additional
-REPL while some packages are being installed/removed in the main REPL."
-  :type 'boolean
-  :group 'guix-repl)
-
-(defcustom guix-repl-socket-file-name-function
-  #'guix-repl-socket-file-name
-  "Function used to define a socket file name used by Guix REPL.
-The function is called without arguments."
-  :type '(choice (function-item guix-repl-socket-file-name)
-                 (function :tag "Other function"))
-  :group 'guix-repl)
-
-(defcustom guix-emacs-activate-after-operation t
-  "Activate Emacs packages after installing.
-If nil, do not load autoloads of the Emacs packages after
-they are successfully installed."
-  :type 'boolean
-  :group 'guix-repl)
-
-(defvar guix-repl-current-socket nil
-  "Name of a socket file used by the current Guix REPL.")
-
-(defvar guix-repl-buffer nil
-  "Main Geiser REPL buffer used for communicating with Guix.
-This REPL is used for processing package actions and for
-receiving information if `guix-use-guile-server' is nil.")
-
-(defvar guix-internal-repl-buffer nil
-  "Additional Geiser REPL buffer used for communicating with Guix.
-This REPL is used for receiving information only if
-`guix-use-guile-server' is non-nil.")
-
-(defvar guix-internal-repl-buffer-name "*Guix Internal REPL*"
-  "Default name of an internal Guix REPL buffer.")
-
-(defvar guix-before-repl-operation-hook nil
-  "Hook run before executing an operation in Guix REPL.")
-
-(defvar guix-after-repl-operation-hook
-  '(guix-repl-autoload-emacs-packages-maybe
-    guix-repl-operation-success-message)
-  "Hook run after executing successful operation in Guix REPL.")
-
-(defvar guix-repl-operation-p nil
-  "Non-nil, if current operation is performed by `guix-eval-in-repl'.
-This internal variable is used to distinguish Guix operations
-from operations performed in Guix REPL by a user.")
-
-(defvar guix-repl-operation-type nil
-  "Type of the current operation performed by `guix-eval-in-repl'.
-This internal variable is used to define what actions should be
-executed after the current operation succeeds.
-See `guix-eval-in-repl' for details.")
-
-(defun guix-repl-autoload-emacs-packages-maybe ()
-  "Load autoloads for Emacs packages if needed.
-See `guix-emacs-activate-after-operation' for details."
-  (and guix-emacs-activate-after-operation
-       ;; FIXME Since a user can work with a non-current profile (using
-       ;; C-u before `guix-search-by-name' and other commands), emacs
-       ;; packages can be installed to another profile, and the
-       ;; following code will not work (i.e., the autoloads for this
-       ;; profile will not be loaded).
-       (guix-emacs-autoload-packages guix-current-profile)))
-
-(defun guix-repl-operation-success-message ()
-  "Message telling about successful Guix operation."
-  (message "Guix operation has been performed."))
-
-(defun guix-get-guile-program (&optional socket)
-  "Return a value suitable for `geiser-guile-binary'."
-  (if (null socket)
-      guix-guile-program
-    (append (if (listp guix-guile-program)
-                guix-guile-program
-              (list guix-guile-program))
-            (list (concat "--listen=" socket)))))
-
-(defun guix-repl-socket-file-name ()
-  "Return a name of a socket file used by Guix REPL."
-  (make-temp-name
-   (concat (file-name-as-directory temporary-file-directory)
-           "guix-repl-")))
-
-(defun guix-repl-delete-socket-maybe ()
-  "Delete `guix-repl-current-socket' file if it exists."
-  (and guix-repl-current-socket
-       (file-exists-p guix-repl-current-socket)
-       (delete-file guix-repl-current-socket)))
-
-(add-hook 'kill-emacs-hook 'guix-repl-delete-socket-maybe)
-
-(defun guix-start-process-maybe (&optional start-msg end-msg)
-  "Start Geiser REPL configured for Guix if needed.
-START-MSG and END-MSG are strings displayed in the minibuffer in
-the beginning and in the end of the starting process.  If nil,
-display default messages."
-  (guix-start-repl-maybe nil
-                         (or start-msg "Starting Guix REPL ...")
-                         (or end-msg "Guix REPL has been started."))
-  (if guix-use-guile-server
-      (guix-start-repl-maybe 'internal)
-    (setq guix-internal-repl-buffer guix-repl-buffer)))
-
-(defun guix-start-repl-maybe (&optional internal start-msg end-msg)
-  "Start Guix REPL if needed.
-If INTERNAL is non-nil, start an internal REPL.
-
-START-MSG and END-MSG are strings displayed in the minibuffer in
-the beginning and in the end of the process.  If nil, do not
-display messages."
-  (let* ((repl-var (guix-get-repl-buffer-variable internal))
-         (repl (symbol-value repl-var)))
-    (unless (and (buffer-live-p repl)
-                 (get-buffer-process repl))
-      (and start-msg (message start-msg))
-      (setq guix-repl-operation-p nil)
-      (unless internal
-        ;; Guile leaves socket file after exit, so remove it if it
-        ;; exists (after the REPL restart).
-        (guix-repl-delete-socket-maybe)
-        (setq guix-repl-current-socket
-              (and guix-use-guile-server
-                   (or guix-repl-current-socket
-                       (funcall guix-repl-socket-file-name-function)))))
-      (let ((geiser-guile-binary (guix-get-guile-program
-                                  (unless internal
-                                    guix-repl-current-socket)))
-            (geiser-guile-init-file (unless internal guix-helper-file))
-            (repl (get-buffer-create
-                   (guix-get-repl-buffer-name internal))))
-        (guix-start-repl repl (and internal guix-repl-current-socket))
-        (set repl-var repl)
-        (and end-msg (message end-msg))
-        (unless internal
-          (run-hooks 'guix-after-start-repl-hook))))))
-
-(defun guix-start-repl (buffer &optional address)
-  "Start Guix REPL in BUFFER.
-If ADDRESS is non-nil, connect to a remote guile process using
-this address (it should be defined by
-`geiser-repl--read-address')."
-  ;; A mix of the code from `geiser-repl--start-repl' and
-  ;; `geiser-repl--to-repl-buffer'.
-  (let ((impl 'guile)
-        (geiser-guile-load-path (cons (expand-file-name guix-load-path)
-                                      geiser-guile-load-path))
-        (geiser-repl-startup-time guix-repl-startup-time))
-    (with-current-buffer buffer
-      (geiser-repl-mode)
-      (geiser-impl--set-buffer-implementation impl)
-      (geiser-repl--autodoc-mode -1)
-      (goto-char (point-max))
-      (let ((prompt (geiser-con--combined-prompt
-                     geiser-guile--prompt-regexp
-                     geiser-guile--debugger-prompt-regexp)))
-        (geiser-repl--save-remote-data address)
-        (geiser-repl--start-scheme impl address prompt)
-        (geiser-repl--quit-setup)
-        (geiser-repl--history-setup)
-        (setq-local geiser-repl--repls (list buffer))
-        (geiser-repl--set-this-buffer-repl buffer)
-        (setq geiser-repl--connection
-              (geiser-con--make-connection
-               (get-buffer-process (current-buffer))
-               geiser-guile--prompt-regexp
-               geiser-guile--debugger-prompt-regexp))
-        (geiser-repl--startup impl address)
-        (geiser-repl--autodoc-mode 1)
-        (geiser-company--setup geiser-repl-company-p)
-        (add-hook 'comint-output-filter-functions
-                  'guix-repl-output-filter
-                  nil t)
-        (set-process-query-on-exit-flag
-         (get-buffer-process (current-buffer))
-         geiser-repl-query-on-kill-p)))))
-
-(defun guix-repl-output-filter (str)
-  "Filter function suitable for `comint-output-filter-functions'.
-This is a replacement for `geiser-repl--output-filter'."
-  (cond
-   ((string-match-p geiser-guile--prompt-regexp str)
-    (geiser-autodoc--disinhibit-autodoc)
-    (when guix-repl-operation-p
-      (setq guix-repl-operation-p nil)
-      (run-hooks 'guix-after-repl-operation-hook)
-      ;; Run hooks specific to the current operation type.
-      (when guix-repl-operation-type
-        (let ((type-hook (intern
-                          (concat "guix-after-"
-                                  (symbol-name guix-repl-operation-type)
-                                  "-hook"))))
-          (setq guix-repl-operation-type nil)
-          (and (boundp type-hook)
-               (run-hooks type-hook))))))
-   ((string-match geiser-guile--debugger-prompt-regexp str)
-    (setq guix-repl-operation-p nil)
-    (geiser-con--connection-set-debugging geiser-repl--connection
-                                          (match-beginning 0))
-    (geiser-autodoc--disinhibit-autodoc))))
-
-(defun guix-repl-exit (&optional internal no-wait)
-  "Exit the current Guix REPL.
-If INTERNAL is non-nil, exit the internal REPL.
-If NO-WAIT is non-nil, do not wait for the REPL process to exit:
-send a kill signal to it and return immediately."
-  (let ((repl (symbol-value (guix-get-repl-buffer-variable internal))))
-    (when (get-buffer-process repl)
-      (with-current-buffer repl
-        (geiser-con--connection-deactivate geiser-repl--connection t)
-        (comint-kill-subjob)
-        (unless no-wait
-          (while (get-buffer-process repl)
-            (sleep-for 0.1)))))))
-
-(defun guix-get-repl-buffer (&optional internal)
-  "Return Guix REPL buffer; start REPL if needed.
-If INTERNAL is non-nil, return an additional internal REPL."
-  (guix-start-process-maybe)
-  (let ((repl (symbol-value (guix-get-repl-buffer-variable internal))))
-    ;; If a new Geiser REPL is started, `geiser-repl--repl' variable may
-    ;; be set to the new value in a Guix REPL, so set it back to a
-    ;; proper value here.
-    (with-current-buffer repl
-      (geiser-repl--set-this-buffer-repl repl))
-    repl))
-
-(defun guix-get-repl-buffer-variable (&optional internal)
-  "Return the name of a variable with a REPL buffer."
-  (if internal
-      'guix-internal-repl-buffer
-    'guix-repl-buffer))
-
-(defun guix-get-repl-buffer-name (&optional internal)
-  "Return the name of a REPL buffer."
-  (if internal
-      guix-internal-repl-buffer-name
-    guix-repl-buffer-name))
-
-(defun guix-switch-to-repl (&optional internal)
-  "Switch to Guix REPL.
-If INTERNAL is non-nil (interactively with prefix), switch to the
-additional internal REPL if it exists."
-  (interactive "P")
-  (geiser-repl--switch-to-buffer (guix-get-repl-buffer internal)))
-
-\f
-;;; Guix directory
-
-(defvar guix-directory nil
-  "Default directory with Guix source.
-If it is not set by a user, it is set after starting Guile REPL.
-This directory is used to define package locations.")
-
-(defun guix-read-directory ()
-  "Return `guix-directory' or prompt for it.
-This function is intended for using in `interactive' forms."
-  (if current-prefix-arg
-      (read-directory-name "Directory with Guix modules: "
-                           guix-directory)
-    guix-directory))
-
-(defun guix-set-directory ()
-  "Set `guix-directory' if needed."
-  (or guix-directory
-      (setq guix-directory
-            (guix-eval-read "%guix-dir"))))
-
-\f
-;;; Evaluating expressions
-
-(defvar guix-operation-buffer nil
-  "Buffer from which the latest Guix operation was performed.")
-
-(defun guix-eval (str)
-  "Evaluate STR with guile expression using Guix REPL.
-See `guix-geiser-eval' for details."
-  (guix-geiser-eval str (guix-get-repl-buffer 'internal)))
-
-(defun guix-eval-read (str)
-  "Evaluate STR with guile expression using Guix REPL.
-See `guix-geiser-eval-read' for details."
-  (guix-geiser-eval-read str (guix-get-repl-buffer 'internal)))
-
-(defun guix-eval-in-repl (str &optional operation-buffer operation-type)
-  "Switch to Guix REPL and evaluate STR with guile expression there.
-If OPERATION-BUFFER is non-nil, it should be a buffer from which
-the current operation was performed.
-
-If OPERATION-TYPE is non-nil, it should be a symbol.  After
-successful executing of the current operation,
-`guix-after-OPERATION-TYPE-hook' is called."
-  (run-hooks 'guix-before-repl-operation-hook)
-  (setq guix-repl-operation-p t
-        guix-repl-operation-type operation-type
-        guix-operation-buffer operation-buffer)
-  (guix-geiser-eval-in-repl str (guix-get-repl-buffer)))
-
-(provide 'guix-backend)
-
-;;; guix-backend.el ends here
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
deleted file mode 100644
index 658cfdb..0000000
--- a/emacs/guix-base.el
+++ /dev/null
@@ -1,377 +0,0 @@
-;;; guix-base.el --- Common definitions   -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides some base and common definitions for guix.el
-;; package.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-backend)
-(require 'guix-guile)
-(require 'guix-read)
-(require 'guix-utils)
-(require 'guix-ui)
-(require 'guix-profiles)
-
-(defgroup guix nil
-  "Settings for Guix package manager and friends."
-  :prefix "guix-"
-  :group 'external)
-
-(defgroup guix-faces nil
-  "Guix faces."
-  :group 'guix
-  :group 'faces)
-
-(defun guix-package-name-specification (name version &optional output)
-  "Return Guix package specification by its NAME, VERSION and OUTPUT."
-  (concat name "@" version
-          (when output (concat ":" output))))
-
-\f
-;;; Location of profiles and manifests
-
-(defun guix-generation-file (profile generation)
-  "Return the file name of a PROFILE's GENERATION."
-  (format "%s-%s-link" profile generation))
-
-(defun guix-packages-profile (profile &optional generation system?)
-  "Return a directory where packages are installed for the
-PROFILE's GENERATION.
-
-If SYSTEM? is non-nil, then PROFILE is considered to be a system
-profile.  Unlike usual profiles, for a system profile, packages
-are placed in 'profile' subdirectory."
-  (let ((profile (if generation
-                     (guix-generation-file profile generation)
-                   profile)))
-    (if system?
-        (expand-file-name "profile" profile)
-      profile)))
-
-(defun guix-manifest-file (profile &optional generation system?)
-  "Return the file name of a PROFILE's manifest.
-See `guix-packages-profile'."
-  (expand-file-name "manifest"
-                    (guix-packages-profile profile generation system?)))
-
-\f
-;;; Actions on packages and generations
-
-(defface guix-operation-option-key
-  '((t :inherit font-lock-warning-face))
-  "Face used for the keys of operation options."
-  :group 'guix-faces)
-
-(defcustom guix-operation-confirm t
-  "If nil, do not prompt to confirm an operation."
-  :type 'boolean
-  :group 'guix)
-
-(defcustom guix-use-substitutes t
-  "If non-nil, use substitutes for the Guix packages."
-  :type 'boolean
-  :group 'guix)
-
-(defvar guix-dry-run nil
-  "If non-nil, do not perform the real actions, just simulate.")
-
-(defvar guix-temp-buffer-name " *Guix temp*"
-  "Name of a buffer used for displaying info before executing operation.")
-
-(defvar guix-operation-option-true-string "yes"
-  "String displayed in the mode-line when operation option is t.")
-
-(defvar guix-operation-option-false-string "no "
-  "String displayed in the mode-line when operation option is nil.")
-
-(defvar guix-operation-option-separator "  |  "
-  "String used in the mode-line to separate operation options.")
-
-(defvar guix-operation-options
-  '((?s "substitutes" guix-use-substitutes)
-    (?d "dry-run"     guix-dry-run))
-  "List of available operation options.
-Each element of the list has a form:
-
-  (KEY NAME VARIABLE)
-
-KEY is a character that may be pressed during confirmation to
-toggle the option.
-NAME is a string displayed in the mode-line.
-VARIABLE is a name of an option variable.")
-
-(defun guix-operation-option-by-key (key)
-  "Return operation option by KEY (character)."
-  (assq key guix-operation-options))
-
-(defun guix-operation-option-key (option)
-  "Return key (character) of the operation OPTION."
-  (car option))
-
-(defun guix-operation-option-name (option)
-  "Return name of the operation OPTION."
-  (nth 1 option))
-
-(defun guix-operation-option-variable (option)
-  "Return name of the variable of the operation OPTION."
-  (nth 2 option))
-
-(defun guix-operation-option-value (option)
-  "Return boolean value of the operation OPTION."
-  (symbol-value (guix-operation-option-variable option)))
-
-(defun guix-operation-option-string-value (option)
-  "Convert boolean value of the operation OPTION to string and return it."
-  (if (guix-operation-option-value option)
-      guix-operation-option-true-string
-    guix-operation-option-false-string))
-
-(defun guix-operation-prompt (&optional prompt)
-  "Prompt a user for continuing the current operation.
-Return non-nil, if the operation should be continued; nil otherwise.
-Ask a user with PROMPT for continuing an operation."
-  (let* ((option-keys (mapcar #'guix-operation-option-key
-                              guix-operation-options))
-         (keys (append '(?y ?n) option-keys))
-         (prompt (concat (propertize (or prompt "Continue operation?")
-                                     'face 'minibuffer-prompt)
-                         " ("
-                         (mapconcat
-                          (lambda (key)
-                            (propertize (string key)
-                                        'face 'guix-operation-option-key))
-                          keys
-                          ", ")
-                         ") ")))
-    (let ((mode-line mode-line-format))
-      (prog1 (guix-operation-prompt-1 prompt keys)
-        (setq mode-line-format mode-line)
-        ;; Clear the minibuffer after prompting.
-        (message "")))))
-
-(defun guix-operation-prompt-1 (prompt keys)
-  "This function is internal for `guix-operation-prompt'."
-  (guix-operation-set-mode-line)
-  (let ((key (read-char-choice prompt (cons ?\C-g keys) t)))
-    (cl-case key
-      (?y t)
-      ((?n ?\C-g) nil)
-      (t (let* ((option (guix-operation-option-by-key key))
-                (var (guix-operation-option-variable option)))
-           (set var (not (symbol-value var)))
-           (guix-operation-prompt-1 prompt keys))))))
-
-(defun guix-operation-set-mode-line ()
-  "Display operation options in the mode-line of the current buffer."
-  (setq mode-line-format
-        (concat (propertize " Options:   "
-                            'face 'mode-line-buffer-id)
-                (mapconcat
-                 (lambda (option)
-                   (let ((key  (guix-operation-option-key option))
-                         (name (guix-operation-option-name option))
-                         (val  (guix-operation-option-string-value option)))
-                     (concat name
-                             " ("
-                             (propertize (string key)
-                                         'face 'guix-operation-option-key)
-                             "): " val)))
-                 guix-operation-options
-                 guix-operation-option-separator)))
-  (force-mode-line-update))
-
-(defun guix-package-source-path (package-id)
-  "Return a store file path to a source of a package PACKAGE-ID."
-  (message "Calculating the source derivation ...")
-  (guix-eval-read
-   (guix-make-guile-expression
-    'package-source-path package-id)))
-
-(defun guix-package-store-path (package-id)
-  "Return a list of store directories of outputs of package PACKAGE-ID."
-  (message "Calculating the package derivation ...")
-  (guix-eval-read
-   (guix-make-guile-expression
-    'package-store-path package-id)))
-
-(defvar guix-after-source-download-hook nil
-  "Hook run after successful performing a 'source-download' operation.")
-
-(defun guix-package-source-build-derivation (package-id &optional prompt)
-  "Build source derivation of a package PACKAGE-ID.
-Ask a user with PROMPT for continuing an operation."
-  (when (or (not guix-operation-confirm)
-            (guix-operation-prompt (or prompt
-                                       "Build the source derivation?")))
-    (guix-eval-in-repl
-     (guix-make-guile-expression
-      'package-source-build-derivation
-      package-id
-      :use-substitutes? (or guix-use-substitutes 'f)
-      :dry-run? (or guix-dry-run 'f))
-     nil 'source-download)))
-
-(defun guix-build-package (package-id &optional prompt)
-  "Build package with PACKAGE-ID.
-Ask a user with PROMPT for continuing the build operation."
-  (when (or (not guix-operation-confirm)
-            (guix-operation-prompt (or prompt "Build package?")))
-    (guix-eval-in-repl
-     (format (concat ",run-in-store "
-                     "(build-package (package-by-id %d)"
-                     " #:use-substitutes? %s"
-                     " #:dry-run? %s)")
-             package-id
-             (guix-guile-boolean guix-use-substitutes)
-             (guix-guile-boolean guix-dry-run)))))
-
-;;;###autoload
-(defun guix-apply-manifest (profile file &optional operation-buffer)
-  "Apply manifest from FILE to PROFILE.
-This function has the same meaning as 'guix package --manifest' command.
-See Info node `(guix) Invoking guix package' for details.
-
-Interactively, use the current profile and prompt for manifest
-FILE.  With a prefix argument, also prompt for PROFILE."
-  (interactive
-   (let* ((current-profile (guix-ui-current-profile))
-          (profile (if current-prefix-arg
-                       (guix-profile-prompt)
-                     (or current-profile guix-current-profile)))
-          (file (read-file-name "File with manifest: "))
-          (buffer (and current-profile (current-buffer))))
-     (list profile file buffer)))
-  (when (or (not guix-operation-confirm)
-            (y-or-n-p (format "Apply manifest from '%s' to profile '%s'? "
-                              file profile)))
-    (guix-eval-in-repl
-     (guix-make-guile-expression
-      'guix-command
-      "package"
-      (concat "--profile="  (expand-file-name profile))
-      (concat "--manifest=" (expand-file-name file)))
-     operation-buffer)))
-
-\f
-;;; Executing guix commands
-
-(defcustom guix-run-in-shell-function #'guix-run-in-shell
-  "Function used to run guix command.
-The function is called with a single argument - a command line string."
-  :type '(choice (function-item guix-run-in-shell)
-                 (function-item guix-run-in-eshell)
-                 (function :tag "Other function"))
-  :group 'guix)
-
-(defcustom guix-shell-buffer-name "*shell*"
-  "Default name of a shell buffer used for running guix commands."
-  :type 'string
-  :group 'guix)
-
-(declare-function comint-send-input "comint" t)
-
-(defun guix-run-in-shell (string)
-  "Run command line STRING in `guix-shell-buffer-name' buffer."
-  (shell guix-shell-buffer-name)
-  (goto-char (point-max))
-  (insert string)
-  (comint-send-input))
-
-(declare-function eshell-send-input "esh-mode" t)
-
-(defun guix-run-in-eshell (string)
-  "Run command line STRING in eshell buffer."
-  (eshell)
-  (goto-char (point-max))
-  (insert string)
-  (eshell-send-input))
-
-(defun guix-run-command-in-shell (args)
-  "Execute 'guix ARGS ...' command in a shell buffer."
-  (funcall guix-run-in-shell-function
-           (guix-command-string args)))
-
-(defun guix-run-command-in-repl (args)
-  "Execute 'guix ARGS ...' command in Guix REPL."
-  (guix-eval-in-repl
-   (apply #'guix-make-guile-expression
-          'guix-command args)))
-
-(defun guix-command-output (args)
-  "Return string with 'guix ARGS ...' output."
-  (cl-multiple-value-bind (output error)
-      (guix-eval (apply #'guix-make-guile-expression
-                        'guix-command-output args))
-    ;; Remove trailing new space from the error string.
-    (message (replace-regexp-in-string "\n\\'" "" (read error)))
-    (read output)))
-
-(defun guix-help-string (&optional commands)
-  "Return string with 'guix COMMANDS ... --help' output."
-  (guix-eval-read
-   (apply #'guix-make-guile-expression
-          'help-string commands)))
-
-\f
-;;; Pull
-
-(defcustom guix-update-after-pull t
-  "If non-nil, update Guix buffers after performing \\[guix-pull]."
-  :type 'boolean
-  :group 'guix)
-
-(defvar guix-after-pull-hook
-  '(guix-restart-repl-after-pull guix-update-buffers-maybe-after-pull)
-  "Hook run after successful performing `guix-pull' operation.")
-
-(defun guix-restart-repl-after-pull ()
-  "Restart Guix REPL after `guix-pull' operation."
-  (guix-repl-exit)
-  (guix-start-process-maybe
-   "Restarting Guix REPL after pull operation ..."))
-
-(defun guix-update-buffers-maybe-after-pull ()
-  "Update buffers depending on `guix-update-after-pull'."
-  (when guix-update-after-pull
-    (mapc #'guix-ui-update-buffer
-          ;; No need to update "generation" buffers.
-          (guix-ui-buffers '(guix-package-list-mode
-                             guix-package-info-mode
-                             guix-output-list-mode
-                             guix-output-info-mode)))
-    (message "Guix buffers have been updated.")))
-
-;;;###autoload
-(defun guix-pull (&optional verbose)
-  "Run Guix pull operation.
-If VERBOSE is non-nil (with prefix argument), produce verbose output."
-  (interactive "P")
-  (let ((args (and verbose '("--verbose"))))
-    (guix-eval-in-repl
-     (apply #'guix-make-guile-expression
-            'guix-command "pull" args)
-     nil 'pull)))
-
-(provide 'guix-base)
-
-;;; guix-base.el ends here
diff --git a/emacs/guix-buffer.el b/emacs/guix-buffer.el
deleted file mode 100644
index 4cefe99..0000000
--- a/emacs/guix-buffer.el
+++ /dev/null
@@ -1,624 +0,0 @@
-;;; guix-buffer.el --- Buffer interface for displaying data  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides a general 'buffer' interface for displaying an
-;; arbitrary data.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-history)
-(require 'guix-utils)
-
-(defvar guix-buffer-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "l") 'guix-history-back)
-    (define-key map (kbd "r") 'guix-history-forward)
-    (define-key map (kbd "g") 'revert-buffer)
-    (define-key map (kbd "R") 'guix-buffer-redisplay)
-    map)
-  "Parent keymap for Guix buffer modes.")
-
-\f
-;;; Buffer item
-
-(cl-defstruct (guix-buffer-item
-               (:constructor nil)
-               (:constructor guix-buffer-make-item
-                             (entries buffer-type entry-type args))
-               (:copier      nil))
-  entries buffer-type entry-type args)
-
-(defvar-local guix-buffer-item nil
-  "Data (structure) for the current Guix buffer.
-The structure consists of the following elements:
-
-- `entries': list of the currently displayed entries.
-
-  Each element of the list is an alist with an entry data of the
-  following form:
-
-    ((PARAM . VAL) ...)
-
-  PARAM is a name of the entry parameter.
-  VAL is a value of this parameter.
-
-- `entry-type': type of the currently displayed entries.
-
-- `buffer-type': type of the current buffer.
-
-- `args': search arguments used to get the current entries.")
-(put 'guix-buffer-item 'permanent-local t)
-
-(defmacro guix-buffer-with-item (item &rest body)
-  "Evaluate BODY using buffer ITEM.
-The following local variables are available inside BODY:
-`%entries', `%buffer-type', `%entry-type', `%args'.
-See `guix-buffer-item' for details."
-  (declare (indent 1) (debug t))
-  (let ((item-var (make-symbol "item")))
-    `(let ((,item-var ,item))
-       (let ((%entries     (guix-buffer-item-entries     ,item-var))
-             (%buffer-type (guix-buffer-item-buffer-type ,item-var))
-             (%entry-type  (guix-buffer-item-entry-type  ,item-var))
-             (%args        (guix-buffer-item-args        ,item-var)))
-         ,@body))))
-
-(defmacro guix-buffer-with-current-item (&rest body)
-  "Evaluate BODY using `guix-buffer-item'.
-See `guix-buffer-with-item' for details."
-  (declare (indent 0) (debug t))
-  `(guix-buffer-with-item guix-buffer-item
-     ,@body))
-
-(defmacro guix-buffer-define-current-item-accessor (name)
-  "Define `guix-buffer-current-NAME' function to access NAME
-element of `guix-buffer-item' structure.
-NAME should be a symbol."
-  (let* ((name-str (symbol-name name))
-         (accessor (intern (concat "guix-buffer-item-" name-str)))
-         (fun-name (intern (concat "guix-buffer-current-" name-str)))
-         (doc      (format "\
-Return '%s' of the current Guix buffer.
-See `guix-buffer-item' for details."
-                           name-str)))
-    `(defun ,fun-name ()
-       ,doc
-       (and guix-buffer-item
-            (,accessor guix-buffer-item)))))
-
-(defmacro guix-buffer-define-current-item-accessors (&rest names)
-  "Define `guix-buffer-current-NAME' functions for NAMES.
-See `guix-buffer-define-current-item-accessor' for details."
-  `(progn
-     ,@(mapcar (lambda (name)
-                 `(guix-buffer-define-current-item-accessor ,name))
-               names)))
-
-(guix-buffer-define-current-item-accessors
- entries entry-type buffer-type args)
-
-(defmacro guix-buffer-define-current-args-accessor (n prefix name)
-  "Define `PREFIX-NAME' function to access Nth element of 'args'
-field of `guix-buffer-item' structure.
-PREFIX and NAME should be strings."
-  (let ((fun-name (intern (concat prefix "-" name)))
-        (doc      (format "\
-Return '%s' of the current Guix buffer.
-'%s' is the element number %d in 'args' of `guix-buffer-item'."
-                          name name n)))
-    `(defun ,fun-name ()
-       ,doc
-       (nth ,n (guix-buffer-current-args)))))
-
-(defmacro guix-buffer-define-current-args-accessors (prefix &rest names)
-  "Define `PREFIX-NAME' functions for NAMES.
-See `guix-buffer-define-current-args-accessor' for details."
-  `(progn
-     ,@(cl-loop for name in names
-                for i from 0
-                collect `(guix-buffer-define-current-args-accessor
-                          ,i ,prefix ,name))))
-
-\f
-;;; Wrappers for defined variables
-
-(defvar guix-buffer-data nil
-  "Alist with 'buffer' data.
-This alist is filled by `guix-buffer-define-interface' macro.")
-
-(defun guix-buffer-value (buffer-type entry-type symbol)
-  "Return SYMBOL's value for BUFFER-TYPE/ENTRY-TYPE from `guix-buffer-data'."
-  (symbol-value
-   (guix-assq-value guix-buffer-data buffer-type entry-type symbol)))
-
-(defun guix-buffer-get-entries (buffer-type entry-type args)
-  "Return ENTRY-TYPE entries.
-Call an appropriate 'get-entries' function from `guix-buffer'
-using ARGS as its arguments."
-  (apply (guix-buffer-value buffer-type entry-type 'get-entries)
-         args))
-
-(defun guix-buffer-mode-enable (buffer-type entry-type)
-  "Turn on major mode to display ENTRY-TYPE ENTRIES in BUFFER-TYPE buffer."
-  (funcall (guix-buffer-value buffer-type entry-type 'mode)))
-
-(defun guix-buffer-mode-initialize (buffer-type entry-type)
-  "Set up the current BUFFER-TYPE buffer to display ENTRY-TYPE entries."
-  (let ((fun (guix-buffer-value buffer-type entry-type 'mode-init)))
-    (when fun
-      (funcall fun))))
-
-(defun guix-buffer-insert-entries (entries buffer-type entry-type)
-  "Show ENTRY-TYPE ENTRIES in the current BUFFER-TYPE buffer."
-  (funcall (guix-buffer-value buffer-type entry-type 'insert-entries)
-           entries))
-
-(defun guix-buffer-show-entries-default (entries buffer-type entry-type)
-  "Show ENTRY-TYPE ENTRIES in the current BUFFER-TYPE buffer."
-  (let ((inhibit-read-only t))
-    (erase-buffer)
-    (guix-buffer-mode-enable buffer-type entry-type)
-    (guix-buffer-insert-entries entries buffer-type entry-type)
-    (goto-char (point-min))))
-
-(defun guix-buffer-show-entries (entries buffer-type entry-type)
-  "Show ENTRY-TYPE ENTRIES in the current BUFFER-TYPE buffer."
-  (funcall (guix-buffer-value buffer-type entry-type 'show-entries)
-           entries))
-
-(defun guix-buffer-message (entries buffer-type entry-type args)
-  "Display a message for BUFFER-ITEM after showing entries."
-  (let ((fun (guix-buffer-value buffer-type entry-type 'message)))
-    (when fun
-      (apply fun entries args))))
-
-(defun guix-buffer-name (buffer-type entry-type args)
-  "Return name of BUFFER-TYPE buffer for displaying ENTRY-TYPE entries."
-  (let ((str-or-fun (guix-buffer-value buffer-type entry-type
-                                       'buffer-name)))
-    (if (stringp str-or-fun)
-        str-or-fun
-      (apply str-or-fun args))))
-
-(defun guix-buffer-param-title (buffer-type entry-type param)
-  "Return PARAM title for BUFFER-TYPE/ENTRY-TYPE."
-  (or (guix-assq-value (guix-buffer-value buffer-type entry-type 'titles)
-                       param)
-      ;; Fallback to a title defined in 'info' interface.
-      (unless (eq buffer-type 'info)
-        (guix-assq-value (guix-buffer-value 'info entry-type 'titles)
-                         param))
-      (guix-symbol-title param)))
-
-(defun guix-buffer-history-size (buffer-type entry-type)
-  "Return history size for BUFFER-TYPE/ENTRY-TYPE."
-  (guix-buffer-value buffer-type entry-type 'history-size))
-
-(defun guix-buffer-revert-confirm? (buffer-type entry-type)
-  "Return 'revert-confirm' value for BUFFER-TYPE/ENTRY-TYPE."
-  (guix-buffer-value buffer-type entry-type 'revert-confirm))
-
-\f
-;;; Displaying entries
-
-(defun guix-buffer-display (buffer)
-  "Switch to a Guix BUFFER."
-  (pop-to-buffer buffer
-                 '((display-buffer-reuse-window
-                    display-buffer-same-window))))
-
-(defun guix-buffer-history-item (buffer-item)
-  "Make and return a history item for displaying BUFFER-ITEM."
-  (list #'guix-buffer-set buffer-item))
-
-(defun guix-buffer-set (buffer-item &optional history)
-  "Set up the current buffer for displaying BUFFER-ITEM.
-HISTORY should be one of the following:
-
-  `nil' - do not save BUFFER-ITEM in history,
-
-  `add' - add it to history,
-
-  `replace' - replace the current history item."
-  (guix-buffer-with-item buffer-item
-    (when %entries
-      ;; Set buffer item before showing entries, so that its value can
-      ;; be used by the code for displaying entries.
-      (setq guix-buffer-item buffer-item)
-      (guix-buffer-show-entries %entries %buffer-type %entry-type)
-      (when history
-        (funcall (cl-ecase history
-                   (add     #'guix-history-add)
-                   (replace #'guix-history-replace))
-                 (guix-buffer-history-item buffer-item))))
-    (guix-buffer-message %entries %buffer-type %entry-type %args)))
-
-(defun guix-buffer-display-entries-current
-    (entries buffer-type entry-type args &optional history)
-  "Show ENTRIES in the current Guix buffer.
-See `guix-buffer-item' for the meaning of BUFFER-TYPE, ENTRY-TYPE
-and ARGS, and `guix-buffer-set' for the meaning of HISTORY."
-  (let ((item (guix-buffer-make-item entries buffer-type
-                                     entry-type args)))
-    (guix-buffer-set item history)))
-
-(defun guix-buffer-get-display-entries-current
-    (buffer-type entry-type args &optional history)
-  "Search for entries and show them in the current Guix buffer.
-See `guix-buffer-display-entries-current' for details."
-  (guix-buffer-display-entries-current
-   (guix-buffer-get-entries buffer-type entry-type args)
-   buffer-type entry-type args history))
-
-(defun guix-buffer-display-entries
-    (entries buffer-type entry-type args &optional history)
-  "Show ENTRIES in a BUFFER-TYPE buffer.
-See `guix-buffer-display-entries-current' for details."
-  (let ((buffer (get-buffer-create
-                 (guix-buffer-name buffer-type entry-type args))))
-    (with-current-buffer buffer
-      (guix-buffer-display-entries-current
-       entries buffer-type entry-type args history))
-    (when entries
-      (guix-buffer-display buffer))))
-
-(defun guix-buffer-get-display-entries
-    (buffer-type entry-type args &optional history)
-  "Search for entries and show them in a BUFFER-TYPE buffer.
-See `guix-buffer-display-entries-current' for details."
-  (guix-buffer-display-entries
-   (guix-buffer-get-entries buffer-type entry-type args)
-   buffer-type entry-type args history))
-
-(defun guix-buffer-revert (_ignore-auto noconfirm)
-  "Update the data in the current Guix buffer.
-This function is suitable for `revert-buffer-function'.
-See `revert-buffer' for the meaning of NOCONFIRM."
-  (guix-buffer-with-current-item
-    (when (or noconfirm
-              (not (guix-buffer-revert-confirm? %buffer-type %entry-type))
-              (y-or-n-p "Update the current buffer? "))
-      (guix-buffer-get-display-entries-current
-       %buffer-type %entry-type %args 'replace))))
-
-(defvar guix-buffer-after-redisplay-hook nil
-  "Hook run by `guix-buffer-redisplay'.
-This hook is called before seting up a window position.")
-
-(defun guix-buffer-redisplay ()
-  "Redisplay the current Guix buffer.
-Restore the point and window positions after redisplaying.
-
-This function does not update the buffer data, use
-'\\[revert-buffer]' if you want the full update."
-  (interactive)
-  (let* ((old-point (point))
-         ;; For simplicity, ignore an unlikely case when multiple
-         ;; windows display the same buffer.
-         (window (car (get-buffer-window-list (current-buffer) nil t)))
-         (window-start (and window (window-start window))))
-    (guix-buffer-set guix-buffer-item)
-    (goto-char old-point)
-    (run-hooks 'guix-buffer-after-redisplay-hook)
-    (when window
-      (set-window-point window (point))
-      (set-window-start window window-start))))
-
-(defun guix-buffer-redisplay-goto-button ()
-  "Redisplay the current buffer and go to the next button, if needed."
-  (let ((guix-buffer-after-redisplay-hook
-         (cons (lambda ()
-                 (unless (button-at (point))
-                   (forward-button 1)))
-               guix-buffer-after-redisplay-hook)))
-    (guix-buffer-redisplay)))
-
-\f
-;;; Interface definers
-
-(defmacro guix-define-groups (type &rest args)
-  "Define `guix-TYPE' and `guix-TYPE-faces' custom groups.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-Optional keywords:
-
-  - `:parent-group' - name of a parent custom group.
-
-  - `:parent-faces-group' - name of a parent custom faces group.
-
-  - `:group-doc' - docstring of a `guix-TYPE' group.
-
-  - `:faces-group-doc' - docstring of a `guix-TYPE-faces' group."
-  (declare (indent 1))
-  (let* ((type-str           (symbol-name type))
-         (prefix             (concat "guix-" type-str))
-         (group              (intern prefix))
-         (faces-group        (intern (concat prefix "-faces"))))
-    (guix-keyword-args-let args
-        ((parent-group       :parent-group 'guix)
-         (parent-faces-group :parent-faces-group 'guix-faces)
-         (group-doc          :group-doc
-                             (format "Settings for '%s' buffers."
-                                     type-str))
-         (faces-group-doc    :faces-group-doc
-                             (format "Faces for '%s' buffers."
-                                     type-str)))
-      `(progn
-         (defgroup ,group nil
-           ,group-doc
-           :group ',parent-group)
-
-         (defgroup ,faces-group nil
-           ,faces-group-doc
-           :group ',group
-           :group ',parent-faces-group)))))
-
-(defmacro guix-define-entry-type (entry-type &rest args)
-  "Define general code for ENTRY-TYPE.
-See `guix-define-groups'."
-  (declare (indent 1))
-  `(guix-define-groups ,entry-type
-     ,@args))
-
-(defmacro guix-define-buffer-type (buffer-type &rest args)
-  "Define general code for BUFFER-TYPE.
-See `guix-define-groups'."
-  (declare (indent 1))
-  `(guix-define-groups ,buffer-type
-     ,@args))
-
-(defmacro guix-buffer-define-interface (buffer-type entry-type &rest args)
-  "Define BUFFER-TYPE interface for displaying ENTRY-TYPE entries.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-In the following description TYPE means ENTRY-TYPE-BUFFER-TYPE.
-
-Required keywords:
-
-  - `:buffer-name' - default value of the generated
-    `guix-TYPE-buffer-name' variable.
-
-  - `:get-entries-function' - default value of the generated
-    `guix-TYPE-get-function' variable.
-
-  - `:show-entries-function' - default value of the generated
-    `guix-TYPE-show-function' variable.
-
-  Alternatively, if `:show-entries-function' is not specified, a
-  default `guix-TYPE-show-entries' will be generated, and the
-  following keyword should be specified instead:
-
-  - `:insert-entries-function' - default value of the generated
-    `guix-TYPE-insert-function' variable.
-
-Optional keywords:
-
-  - `:message-function' - default value of the generated
-    `guix-TYPE-message-function' variable.
-
-  - `:titles' - default value of the generated
-    `guix-TYPE-titles' variable.
-
-  - `:history-size' - default value of the generated
-    `guix-TYPE-history-size' variable.
-
-  - `:revert-confirm?' - default value of the generated
-    `guix-TYPE-revert-confirm' variable.
-
-  - `:mode-name' - name (a string appeared in the mode-line) of
-     the generated `guix-TYPE-mode'.
-
-  - `:mode-init-function' - default value of the generated
-    `guix-TYPE-mode-initialize-function' variable.
-
-  - `:reduced?' - if non-nil, generate only group, faces group
-    and titles variable (if specified); all keywords become
-    optional."
-  (declare (indent 2))
-  (let* ((entry-type-str     (symbol-name entry-type))
-         (buffer-type-str    (symbol-name buffer-type))
-         (prefix             (concat "guix-" entry-type-str "-"
-                                     buffer-type-str))
-         (group              (intern prefix))
-         (faces-group        (intern (concat prefix "-faces")))
-         (get-entries-var    (intern (concat prefix "-get-function")))
-         (show-entries-var   (intern (concat prefix "-show-function")))
-         (show-entries-fun   (intern (concat prefix "-show-entries")))
-         (message-var        (intern (concat prefix "-message-function")))
-         (buffer-name-var    (intern (concat prefix "-buffer-name")))
-         (titles-var         (intern (concat prefix "-titles")))
-         (history-size-var   (intern (concat prefix "-history-size")))
-         (revert-confirm-var (intern (concat prefix "-revert-confirm"))))
-    (guix-keyword-args-let args
-        ((get-entries-val    :get-entries-function)
-         (show-entries-val   :show-entries-function)
-         (insert-entries-val :insert-entries-function)
-         (mode-name          :mode-name (capitalize prefix))
-         (mode-init-val      :mode-init-function)
-         (message-val        :message-function)
-         (buffer-name-val    :buffer-name)
-         (titles-val         :titles)
-         (history-size-val   :history-size 20)
-         (revert-confirm-val :revert-confirm? t)
-         (reduced?           :reduced?))
-      `(progn
-         (defgroup ,group nil
-           ,(format "Displaying '%s' entries in '%s' buffer."
-                    entry-type-str buffer-type-str)
-           :group ',(intern (concat "guix-" entry-type-str))
-           :group ',(intern (concat "guix-" buffer-type-str)))
-
-         (defgroup ,faces-group nil
-           ,(format "Faces for displaying '%s' entries in '%s' buffer."
-                    entry-type-str buffer-type-str)
-           :group ',group
-           :group ',(intern (concat "guix-" entry-type-str "-faces"))
-           :group ',(intern (concat "guix-" buffer-type-str "-faces")))
-
-         (defcustom ,titles-var ,titles-val
-           ,(format "Alist of titles of '%s' parameters."
-                    entry-type-str)
-           :type '(alist :key-type symbol :value-type string)
-           :group ',group)
-
-         ,(unless reduced?
-            `(progn
-               (defvar ,get-entries-var ,get-entries-val
-                 ,(format "\
-Function used to receive '%s' entries for '%s' buffer."
-                          entry-type-str buffer-type-str))
-
-               (defvar ,show-entries-var
-                 ,(or show-entries-val `',show-entries-fun)
-                 ,(format "\
-Function used to show '%s' entries in '%s' buffer."
-                          entry-type-str buffer-type-str))
-
-               (defvar ,message-var ,message-val
-                 ,(format "\
-Function used to display a message after showing '%s' entries.
-If nil, do not display messages."
-                          entry-type-str))
-
-               (defcustom ,buffer-name-var ,buffer-name-val
-                 ,(format "\
-Default name of '%s' buffer for displaying '%s' entries.
-May be a string or a function returning a string.  The function
-is called with the same arguments as `%S'."
-                          buffer-type-str entry-type-str get-entries-var)
-                 :type '(choice string function)
-                 :group ',group)
-
-               (defcustom ,history-size-var ,history-size-val
-                 ,(format "\
-Maximum number of items saved in history of `%S' buffer.
-If 0, the history is disabled."
-                          buffer-name-var)
-                 :type 'integer
-                 :group ',group)
-
-               (defcustom ,revert-confirm-var ,revert-confirm-val
-                 ,(format "\
-If non-nil, ask to confirm for reverting `%S' buffer."
-                          buffer-name-var)
-                 :type 'boolean
-                 :group ',group)
-
-               (guix-alist-put!
-                '((get-entries    . ,get-entries-var)
-                  (show-entries   . ,show-entries-var)
-                  (message        . ,message-var)
-                  (buffer-name    . ,buffer-name-var)
-                  (history-size   . ,history-size-var)
-                  (revert-confirm . ,revert-confirm-var))
-                'guix-buffer-data ',buffer-type ',entry-type)
-
-               ,(unless show-entries-val
-                  `(defun ,show-entries-fun (entries)
-                     ,(format "\
-Show '%s' ENTRIES in the current '%s' buffer."
-                              entry-type-str buffer-type-str)
-                     (guix-buffer-show-entries-default
-                      entries ',buffer-type ',entry-type)))
-
-               ,(when (or insert-entries-val
-                          (null show-entries-val))
-                  (let ((insert-entries-var
-                         (intern (concat prefix "-insert-function"))))
-                    `(progn
-                       (defvar ,insert-entries-var ,insert-entries-val
-                         ,(format "\
-Function used to print '%s' entries in '%s' buffer."
-                                  entry-type-str buffer-type-str))
-
-                       (guix-alist-put!
-                        ',insert-entries-var 'guix-buffer-data
-                        ',buffer-type ',entry-type
-                        'insert-entries))))
-
-               ,(when (or mode-name
-                          mode-init-val
-                          (null show-entries-val))
-                  (let* ((mode-str      (concat prefix "-mode"))
-                         (mode-map-str  (concat mode-str "-map"))
-                         (mode          (intern mode-str))
-                         (parent-mode   (intern
-                                         (concat "guix-" buffer-type-str
-                                                 "-mode")))
-                         (mode-var      (intern
-                                         (concat mode-str "-function")))
-                         (mode-init-var (intern
-                                         (concat mode-str
-                                                 "-initialize-function"))))
-                    `(progn
-                       (defvar ,mode-var ',mode
-                         ,(format "\
-Major mode for displaying '%s' entries in '%s' buffer."
-                                  entry-type-str buffer-type-str))
-
-                       (defvar ,mode-init-var ,mode-init-val
-                         ,(format "\
-Function used to set up '%s' buffer for displaying '%s' entries."
-                                  buffer-type-str entry-type-str))
-
-                       (define-derived-mode ,mode ,parent-mode ,mode-name
-                         ,(format "\
-Major mode for displaying '%s' entries in '%s' buffer.
-
-\\{%s}"
-                                  entry-type-str buffer-type-str mode-map-str)
-                         (setq-local revert-buffer-function
-                                     'guix-buffer-revert)
-                         (setq-local guix-history-size
-                                     (guix-buffer-history-size
-                                      ',buffer-type ',entry-type))
-                         (guix-buffer-mode-initialize
-                          ',buffer-type ',entry-type))
-
-                       (guix-alist-put!
-                        ',mode-var 'guix-buffer-data
-                        ',buffer-type ',entry-type 'mode)
-                       (guix-alist-put!
-                        ',mode-init-var 'guix-buffer-data
-                        ',buffer-type ',entry-type
-                        'mode-init))))))
-
-         (guix-alist-put!
-          ',titles-var 'guix-buffer-data
-          ',buffer-type ',entry-type 'titles)))))
-
-\f
-(defvar guix-buffer-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group (or "guix-buffer-with-item"
-                           "guix-buffer-with-current-item"
-                           "guix-buffer-define-interface"
-                           "guix-define-groups"
-                           "guix-define-entry-type"
-                           "guix-define-buffer-type"))
-            symbol-end)
-       . 1))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-buffer-font-lock-keywords)
-
-(provide 'guix-buffer)
-
-;;; guix-buffer.el ends here
diff --git a/emacs/guix-build-log.el b/emacs/guix-build-log.el
deleted file mode 100644
index f67be16..0000000
--- a/emacs/guix-build-log.el
+++ /dev/null
@@ -1,381 +0,0 @@
-;;; guix-build-log.el --- Major and minor modes for build logs   -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides a major mode (`guix-build-log-mode') and a minor mode
-;; (`guix-build-log-minor-mode') for highlighting Guix build logs.
-
-;;; Code:
-
-(require 'guix-utils)
-
-(defgroup guix-build-log nil
-  "Settings for `guix-build-log-mode'."
-  :group 'guix)
-
-(defgroup guix-build-log-faces nil
-  "Faces for `guix-build-log-mode'."
-  :group 'guix-build-log
-  :group 'guix-faces)
-
-(defface guix-build-log-title-head
-  '((t :inherit font-lock-keyword-face))
-  "Face for '@' symbol of a log title."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-title-start
-  '((t :inherit guix-build-log-title-head))
-  "Face for a log title denoting a start of a process."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-title-success
-  '((t :inherit guix-build-log-title-head))
-  "Face for a log title denoting a successful end of a process."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-title-fail
-  '((t :inherit error))
-  "Face for a log title denoting a failed end of a process."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-title-end
-  '((t :inherit guix-build-log-title-head))
-  "Face for a log title denoting an undefined end of a process."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-phase-name
-  '((t :inherit font-lock-function-name-face))
-  "Face for a phase name."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-phase-start
-  '((default :weight bold)
-    (((class grayscale) (background light)) :foreground "Gray90")
-    (((class grayscale) (background dark))  :foreground "DimGray")
-    (((class color) (min-colors 16) (background light))
-     :foreground "DarkGreen")
-    (((class color) (min-colors 16) (background dark))
-     :foreground "LimeGreen")
-    (((class color) (min-colors 8)) :foreground "green"))
-  "Face for the start line of a phase."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-phase-end
-  '((((class grayscale) (background light)) :foreground "Gray90")
-    (((class grayscale) (background dark))  :foreground "DimGray")
-    (((class color) (min-colors 16) (background light))
-     :foreground "ForestGreen")
-    (((class color) (min-colors 16) (background dark))
-     :foreground "LightGreen")
-    (((class color) (min-colors 8)) :foreground "green")
-    (t :weight bold))
-  "Face for the end line of a phase."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-phase-success
-  '((t))
-  "Face for the 'succeeded' word of a phase line."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-phase-fail
-  '((t :inherit error))
-  "Face for the 'failed' word of a phase line."
-  :group 'guix-build-log-faces)
-
-(defface guix-build-log-phase-seconds
-  '((t :inherit font-lock-constant-face))
-  "Face for the number of seconds for a phase."
-  :group 'guix-build-log-faces)
-
-(defcustom guix-build-log-minor-mode-activate t
-  "If non-nil, then `guix-build-log-minor-mode' is automatically
-activated in `shell-mode' buffers."
-  :type 'boolean
-  :group 'guix-build-log)
-
-(defcustom guix-build-log-mode-hook '()
-  "Hook run after `guix-build-log-mode' is entered."
-  :type 'hook
-  :group 'guix-build-log)
-
-(defvar guix-build-log-phase-name-regexp "`\\([^']+\\)'"
-  "Regexp for a phase name.")
-
-(defvar guix-build-log-phase-start-regexp
-  (concat "^starting phase " guix-build-log-phase-name-regexp)
-  "Regexp for the start line of a 'build' phase.")
-
-(defun guix-build-log-title-regexp (&optional state)
-  "Return regexp for the log title.
-STATE is a symbol denoting a state of the title.  It should be
-`start', `fail', `success' or `nil' (for a regexp matching any
-state)."
-  (let* ((word-rx (rx (1+ (any word "-"))))
-         (state-rx (cond ((eq state 'start)   (concat word-rx "started"))
-                         ((eq state 'success) (concat word-rx "succeeded"))
-                         ((eq state 'fail)    (concat word-rx "failed"))
-                         (t word-rx))))
-    (rx-to-string
-     `(and bol (group "@") " " (group (regexp ,state-rx)))
-     t)))
-
-(defun guix-build-log-phase-end-regexp (&optional state)
-  "Return regexp for the end line of a 'build' phase.
-STATE is a symbol denoting how a build phase was ended.  It should be
-`fail', `success' or `nil' (for a regexp matching any state)."
-  (let ((state-rx (cond ((eq state 'success) "succeeded")
-                        ((eq state 'fail)    "failed")
-                        (t (regexp-opt '("succeeded" "failed"))))))
-    (rx-to-string
-     `(and bol "phase " (regexp ,guix-build-log-phase-name-regexp)
-           " " (group (regexp ,state-rx)) " after "
-           (group (1+ (or digit "."))) " seconds")
-     t)))
-
-(defvar guix-build-log-phase-end-regexp
-  ;; For efficiency, it is better to have a regexp for the general line
-  ;; of the phase end, then to call the function all the time.
-  (guix-build-log-phase-end-regexp)
-  "Regexp for the end line of a 'build' phase.")
-
-(defvar guix-build-log-font-lock-keywords
-  `((,(guix-build-log-title-regexp 'start)
-     (1 'guix-build-log-title-head)
-     (2 'guix-build-log-title-start))
-    (,(guix-build-log-title-regexp 'success)
-     (1 'guix-build-log-title-head)
-     (2 'guix-build-log-title-success))
-    (,(guix-build-log-title-regexp 'fail)
-     (1 'guix-build-log-title-head)
-     (2 'guix-build-log-title-fail))
-    (,(guix-build-log-title-regexp)
-     (1 'guix-build-log-title-head)
-     (2 'guix-build-log-title-end))
-    (,guix-build-log-phase-start-regexp
-     (0 'guix-build-log-phase-start)
-     (1 'guix-build-log-phase-name prepend))
-    (,(guix-build-log-phase-end-regexp 'success)
-     (0 'guix-build-log-phase-end)
-     (1 'guix-build-log-phase-name prepend)
-     (2 'guix-build-log-phase-success prepend)
-     (3 'guix-build-log-phase-seconds prepend))
-    (,(guix-build-log-phase-end-regexp 'fail)
-     (0 'guix-build-log-phase-end)
-     (1 'guix-build-log-phase-name prepend)
-     (2 'guix-build-log-phase-fail prepend)
-     (3 'guix-build-log-phase-seconds prepend)))
-  "A list of `font-lock-keywords' for `guix-build-log-mode'.")
-
-(defvar guix-build-log-common-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M-n") 'guix-build-log-next-phase)
-    (define-key map (kbd "M-p") 'guix-build-log-previous-phase)
-    (define-key map (kbd "TAB") 'guix-build-log-phase-toggle)
-    (define-key map (kbd "<tab>") 'guix-build-log-phase-toggle)
-    (define-key map (kbd "<backtab>") 'guix-build-log-phase-toggle-all)
-    (define-key map [(shift tab)] 'guix-build-log-phase-toggle-all)
-    map)
-  "Parent keymap for 'build-log' buffers.
-For `guix-build-log-mode' this map is used as is.
-For `guix-build-log-minor-mode' this map is prefixed with 'C-c'.")
-
-(defvar guix-build-log-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent
-     map (make-composed-keymap (list guix-build-log-common-map)
-                               special-mode-map))
-    (define-key map (kbd "c") 'compilation-shell-minor-mode)
-    (define-key map (kbd "v") 'view-mode)
-    map)
-  "Keymap for `guix-build-log-mode' buffers.")
-
-(defvar guix-build-log-minor-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c") guix-build-log-common-map)
-    map)
-  "Keymap for `guix-build-log-minor-mode' buffers.")
-
-(defun guix-build-log-phase-start (&optional with-header?)
-  "Return the start point of the current build phase.
-If WITH-HEADER? is non-nil, do not skip 'starting phase ...' header.
-Return nil, if there is no phase start before the current point."
-  (save-excursion
-    (end-of-line)
-    (when (re-search-backward guix-build-log-phase-start-regexp nil t)
-      (unless with-header? (end-of-line))
-      (point))))
-
-(defun guix-build-log-phase-end ()
-  "Return the end point of the current build phase."
-  (save-excursion
-    (beginning-of-line)
-    (when (re-search-forward guix-build-log-phase-end-regexp nil t)
-      (point))))
-
-(defun guix-build-log-phase-hide ()
-  "Hide the body of the current build phase."
-  (interactive)
-  (let ((beg (guix-build-log-phase-start))
-        (end (guix-build-log-phase-end)))
-    (when (and beg end)
-      ;; If not on the header line, move to it.
-      (when (and (> (point) beg)
-                 (< (point) end))
-        (goto-char (guix-build-log-phase-start t)))
-      (remove-overlays beg end 'invisible t)
-      (let ((o (make-overlay beg end)))
-        (overlay-put o 'evaporate t)
-        (overlay-put o 'invisible t)))))
-
-(defun guix-build-log-phase-show ()
-  "Show the body of the current build phase."
-  (interactive)
-  (let ((beg (guix-build-log-phase-start))
-        (end (guix-build-log-phase-end)))
-    (when (and beg end)
-      (remove-overlays beg end 'invisible t))))
-
-(defun guix-build-log-phase-hidden-p ()
-  "Return non-nil, if the body of the current build phase is hidden."
-  (let ((beg (guix-build-log-phase-start)))
-    (and beg
-         (cl-some (lambda (o)
-                    (overlay-get o 'invisible))
-                  (overlays-at beg)))))
-
-(defun guix-build-log-phase-toggle-function ()
-  "Return a function to toggle the body of the current build phase."
-  (if (guix-build-log-phase-hidden-p)
-      #'guix-build-log-phase-show
-    #'guix-build-log-phase-hide))
-
-(defun guix-build-log-phase-toggle ()
-  "Show/hide the body of the current build phase."
-  (interactive)
-  (funcall (guix-build-log-phase-toggle-function)))
-
-(defun guix-build-log-phase-toggle-all ()
-  "Show/hide the bodies of all build phases."
-  (interactive)
-  (save-excursion
-    ;; Some phases may be hidden, and some shown.  Whether to hide or to
-    ;; show them, it is determined by the state of the first phase here.
-    (goto-char (point-min))
-    (let ((fun (save-excursion
-                 (re-search-forward guix-build-log-phase-start-regexp nil t)
-                 (guix-build-log-phase-toggle-function))))
-      (while (re-search-forward guix-build-log-phase-start-regexp nil t)
-        (funcall fun)))))
-
-(defun guix-build-log-next-phase (&optional arg)
-  "Move to the next build phase.
-With ARG, do it that many times.  Negative ARG means move
-backward."
-  (interactive "^p")
-  (if arg
-      (when (zerop arg) (user-error "Try again"))
-    (setq arg 1))
-  (let ((search-fun (if (> arg 0)
-                        #'re-search-forward
-                      #'re-search-backward))
-        (n (abs arg))
-        found last-found)
-    (save-excursion
-      (end-of-line (if (> arg 0) 1 0))  ; skip the current line
-      (while (and (not (zerop n))
-                  (setq found
-                        (funcall search-fun
-                                 guix-build-log-phase-start-regexp
-                                 nil t)))
-        (setq n (1- n)
-              last-found found)))
-    (when last-found
-      (goto-char last-found)
-      (forward-line 0))
-    (or found
-        (user-error (if (> arg 0)
-                        "No next build phase"
-                      "No previous build phase")))))
-
-(defun guix-build-log-previous-phase (&optional arg)
-  "Move to the previous build phase.
-With ARG, do it that many times.  Negative ARG means move
-forward."
-  (interactive "^p")
-  (guix-build-log-next-phase (- (or arg 1))))
-
-;;;###autoload
-(define-derived-mode guix-build-log-mode special-mode
-  "Guix-Build-Log"
-  "Major mode for viewing Guix build logs.
-
-\\{guix-build-log-mode-map}"
-  (setq font-lock-defaults '(guix-build-log-font-lock-keywords t)))
-
-;;;###autoload
-(define-minor-mode guix-build-log-minor-mode
-  "Toggle Guix Build Log minor mode.
-
-With a prefix argument ARG, enable Guix Build Log minor mode if
-ARG is positive, and disable it otherwise.  If called from Lisp,
-enable the mode if ARG is omitted or nil.
-
-When Guix Build Log minor mode is enabled, it highlights build
-log in the current buffer.  This mode can be enabled
-programmatically using hooks:
-
-  (add-hook 'shell-mode-hook 'guix-build-log-minor-mode)
-
-\\{guix-build-log-minor-mode-map}"
-  :init-value nil
-  :lighter " Guix-Build-Log"
-  :keymap guix-build-log-minor-mode-map
-  :group 'guix-build-log
-  (if guix-build-log-minor-mode
-      (font-lock-add-keywords nil guix-build-log-font-lock-keywords)
-    (font-lock-remove-keywords nil guix-build-log-font-lock-keywords))
-  (when font-lock-mode
-    (font-lock-fontify-buffer)))
-
-;;;###autoload
-(defun guix-build-log-minor-mode-activate-maybe ()
-  "Activate `guix-build-log-minor-mode' depending on
-`guix-build-log-minor-mode-activate' variable."
-  (when guix-build-log-minor-mode-activate
-    (guix-build-log-minor-mode)))
-
-(defun guix-build-log-find-file (file-or-url)
-  "Open FILE-OR-URL in `guix-build-log-mode'."
-  (guix-find-file-or-url file-or-url)
-  (guix-build-log-mode))
-
-;;;###autoload
-(add-hook 'shell-mode-hook 'guix-build-log-minor-mode-activate-maybe)
-
-;;;###autoload
-(add-to-list 'auto-mode-alist
-             ;; Regexp for log files (usually placed in /var/log/guix/...)
-             (cons (rx "/guix/drvs/" (= 2 alnum) "/" (= 30 alnum)
-                       "-" (+ (any alnum "-+.")) ".drv" string-end)
-                   'guix-build-log-mode))
-
-(provide 'guix-build-log)
-
-;;; guix-build-log.el ends here
diff --git a/emacs/guix-command.el b/emacs/guix-command.el
deleted file mode 100644
index 7069c51..0000000
--- a/emacs/guix-command.el
+++ /dev/null
@@ -1,830 +0,0 @@
-;;; guix-command.el --- Popup interface for guix commands  -*- lexical-binding: t -*-
-
-;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides a magit-like popup interface for running guix
-;; commands in Guix REPL.  The entry point is "M-x guix".  When it is
-;; called the first time, "guix --help" output is parsed and
-;; `guix-COMMAND-action' functions are generated for each available guix
-;; COMMAND.  Then a window with these commands is popped up.  When a
-;; particular COMMAND is called, "guix COMMAND --help" output is parsed,
-;; and a user get a new popup window with available options for this
-;; command and so on.
-
-;; To avoid hard-coding all guix options, actions, etc., as much data is
-;; taken from "guix ... --help" outputs as possible.  But this data is
-;; still incomplete: not all long options have short analogs, also
-;; special readers should be used for some options (for example, to
-;; complete package names while prompting for a package).  So after
-;; parsing --help output, the arguments are "improved".  All arguments
-;; (switches, options and actions) are `guix-command-argument'
-;; structures.
-
-;; Only "M-x guix" command is available after this file is loaded.  The
-;; rest commands/actions/popups are generated on the fly only when they
-;; are needed (that's why there is a couple of `eval'-s in this file).
-
-;; COMMANDS argument is used by many functions in this file.  It means a
-;; list of guix commands without "guix" itself, e.g.: ("build"),
-;; ("import" "gnu").  The empty list stands for the plain "guix" without
-;; subcommands.
-
-;; All actions in popup windows are divided into 2 groups:
-;;
-;; - 'Popup' actions - used to pop up another window.  For example, every
-;;   action in the 'guix' or 'guix import' window is a popup action.  They
-;;   are defined by `guix-command-define-popup-action' macro.
-;;
-;; - 'Execute' actions - used to do something with the command line (to
-;;   run a command in Guix REPL or to copy it into kill-ring) constructed
-;;   with the current popup.  They are defined by
-;;   `guix-command-define-execute-action' macro.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-popup)
-(require 'guix-utils)
-(require 'guix-help-vars)
-(require 'guix-read)
-(require 'guix-base)
-(require 'guix-build-log)
-(require 'guix-guile)
-(require 'guix-external)
-
-(defgroup guix-commands nil
-  "Settings for guix popup windows."
-  :group 'guix)
-
-(defvar guix-command-complex-with-shared-arguments
-  '("system")
-  "List of guix commands which have subcommands with shared options.
-I.e., 'guix foo --help' is the same as 'guix foo bar --help'.")
-
-(defun guix-command-action-name (&optional commands &rest name-parts)
-  "Return name of action function for guix COMMANDS."
-  (guix-command-symbol (append commands name-parts (list "action"))))
-
-\f
-;;; Command arguments
-
-(cl-defstruct (guix-command-argument
-               (:constructor guix-command-make-argument)
-               (:copier      guix-command-copy-argument))
-  name char doc fun switch? option? action?)
-
-(cl-defun guix-command-modify-argument
-    (argument &key
-              (name    nil name-bound?)
-              (char    nil char-bound?)
-              (doc     nil doc-bound?)
-              (fun     nil fun-bound?)
-              (switch? nil switch?-bound?)
-              (option? nil option?-bound?)
-              (action? nil action?-bound?))
-  "Return a modified version of ARGUMENT."
-  (declare (indent 1))
-  (let ((copy (guix-command-copy-argument argument)))
-    (and name-bound?    (setf (guix-command-argument-name    copy) name))
-    (and char-bound?    (setf (guix-command-argument-char    copy) char))
-    (and doc-bound?     (setf (guix-command-argument-doc     copy) doc))
-    (and fun-bound?     (setf (guix-command-argument-fun     copy) fun))
-    (and switch?-bound? (setf (guix-command-argument-switch? copy) switch?))
-    (and option?-bound? (setf (guix-command-argument-option? copy) option?))
-    (and action?-bound? (setf (guix-command-argument-action? copy) action?))
-    copy))
-
-(defun guix-command-modify-argument-from-alist (argument alist)
-  "Return a modified version of ARGUMENT or nil if it wasn't modified.
-Each assoc from ALIST have a form (NAME . PLIST).  NAME is an
-argument name.  PLIST is a property list of argument parameters
-to be modified."
-  (let* ((name  (guix-command-argument-name argument))
-         (plist (guix-assoc-value alist name)))
-    (when plist
-      (apply #'guix-command-modify-argument
-             argument plist))))
-
-(defmacro guix-command-define-argument-improver (name alist)
-  "Define NAME variable and function to modify an argument from ALIST."
-  (declare (indent 1))
-  `(progn
-     (defvar ,name ,alist)
-     (defun ,name (argument)
-       (guix-command-modify-argument-from-alist argument ,name))))
-
-(guix-command-define-argument-improver
-    guix-command-improve-action-argument
-  '(("container"   :char ?C)
-    ("graph"       :char ?G)
-    ("environment" :char ?E)
-    ("publish"     :char ?u)
-    ("pull"        :char ?P)
-    ("size"        :char ?z)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-common-argument
-  '(("--help"    :switch? nil)
-    ("--version" :switch? nil)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-target-argument
-  '(("--target" :char ?T)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-system-type-argument
-  '(("--system" :fun guix-read-system-type)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-load-path-argument
-  '(("--load-path" :fun read-directory-name)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-search-paths-argument
-  '(("--search-paths" :char ?P)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-substitute-urls-argument
-  '(("--substitute-urls" :char ?U)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-hash-argument
-  '(("--format" :fun guix-read-hash-format)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-key-policy-argument
-  '(("--key-download" :fun guix-read-key-policy)))
-
-(defvar guix-command-improve-common-build-argument
-  '(("--no-substitutes"  :char ?s)
-    ("--no-build-hook"   :char ?h)
-    ("--max-silent-time" :char ?x)
-    ("--rounds"          :char ?R :fun read-number)
-    ("--with-input"      :char ?W)))
-
-(defun guix-command-improve-common-build-argument (argument)
-  (guix-command-modify-argument-from-alist
-   argument
-   (append guix-command-improve-load-path-argument
-           guix-command-improve-substitute-urls-argument
-           guix-command-improve-common-build-argument)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-archive-argument
-  '(("--generate-key" :char ?k)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-build-argument
-  '(("--no-grafts"   :char ?g)
-    ("--file"        :fun guix-read-file-name)
-    ("--root"        :fun guix-read-file-name)
-    ("--sources"     :char ?S :fun guix-read-source-type :switch? nil)
-    ("--with-source" :fun guix-read-file-name)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-environment-argument
-  '(("--ad-hoc"
-     :name "--ad-hoc " :fun guix-read-package-names-string
-     :switch? nil :option? t)
-    ("--expose" :char ?E)
-    ("--share" :char ?S)
-    ("--load" :fun guix-read-file-name)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-gc-argument
-  '(("--list-dead" :char ?D)
-    ("--list-live" :char ?L)
-    ("--referrers" :char ?f)
-    ("--verify"    :fun guix-read-verify-options-string)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-graph-argument
-  '(("--type" :fun guix-read-graph-type)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-import-argument
-  '(("cran" :char ?r)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-import-elpa-argument
-  '(("--archive" :fun guix-read-elpa-archive)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-lint-argument
-  '(("--checkers" :fun guix-read-lint-checker-names-string)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-package-argument
-  ;; Unlike all other options, --install/--remove do not have a form
-  ;; '--install=foo,bar' but '--install foo bar' instead, so we need
-  ;; some tweaks.
-  '(("--install"
-     :name "--install " :fun guix-read-package-names-string
-     :switch? nil :option? t)
-    ("--remove"
-     :name "--remove "  :fun guix-read-package-names-string
-     :switch? nil :option? t)
-    ("--install-from-file" :fun guix-read-file-name)
-    ("--manifest"       :fun guix-read-file-name)
-    ("--profile"        :fun guix-read-file-name)
-    ("--do-not-upgrade" :char ?U)
-    ("--roll-back"      :char ?R)
-    ("--show"           :char ?w :fun guix-read-package-name)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-refresh-argument
-  '(("--select"     :fun guix-read-refresh-subset)
-    ("--type"       :fun guix-read-refresh-updater-names-string)
-    ("--key-server" :char ?S)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-size-argument
-  '(("--map-file" :fun guix-read-file-name)))
-
-(guix-command-define-argument-improver
-    guix-command-improve-system-argument
-  '(("disk-image"  :char ?D)
-    ("vm-image"    :char ?V)
-    ("--on-error"  :char ?E)
-    ("--no-grub"   :char ?g)
-    ("--full-boot" :char ?b)))
-
-(defvar guix-command-argument-improvers
-  '((()
-     guix-command-improve-action-argument)
-    (("archive")
-     guix-command-improve-common-build-argument
-     guix-command-improve-target-argument
-     guix-command-improve-system-type-argument
-     guix-command-improve-archive-argument)
-    (("build")
-     guix-command-improve-common-build-argument
-     guix-command-improve-target-argument
-     guix-command-improve-system-type-argument
-     guix-command-improve-build-argument)
-    (("download")
-     guix-command-improve-hash-argument)
-    (("hash")
-     guix-command-improve-hash-argument)
-    (("environment")
-     guix-command-improve-common-build-argument
-     guix-command-improve-search-paths-argument
-     guix-command-improve-system-type-argument
-     guix-command-improve-environment-argument)
-    (("gc")
-     guix-command-improve-gc-argument)
-    (("graph")
-     guix-command-improve-graph-argument)
-    (("import")
-     guix-command-improve-import-argument)
-    (("import" "gnu")
-     guix-command-improve-key-policy-argument)
-    (("import" "elpa")
-     guix-command-improve-import-elpa-argument)
-    (("lint")
-     guix-command-improve-lint-argument)
-    (("package")
-     guix-command-improve-common-build-argument
-     guix-command-improve-search-paths-argument
-     guix-command-improve-package-argument)
-    (("refresh")
-     guix-command-improve-key-policy-argument
-     guix-command-improve-refresh-argument)
-    (("size")
-     guix-command-improve-system-type-argument
-     guix-command-improve-substitute-urls-argument
-     guix-command-improve-size-argument)
-    (("system")
-     guix-command-improve-common-build-argument
-     guix-command-improve-system-argument))
-  "Alist of guix commands and argument improvers for them.")
-
-(defun guix-command-improve-argument (argument improvers)
-  "Return ARGUMENT modified with IMPROVERS."
-  (or (cl-some (lambda (improver)
-                 (funcall improver argument))
-               improvers)
-      argument))
-
-(defun guix-command-improve-arguments (arguments commands)
-  "Return ARGUMENTS for 'guix COMMANDS ...' modified for popup interface."
-  (let ((improvers (cons 'guix-command-improve-common-argument
-                         (guix-assoc-value guix-command-argument-improvers
-                                           commands))))
-    (mapcar (lambda (argument)
-              (guix-command-improve-argument argument improvers))
-            arguments)))
-
-(defun guix-command-parse-arguments (&optional commands)
-  "Return a list of parsed 'guix COMMANDS ...' arguments."
-  (with-temp-buffer
-    (insert (guix-help-string commands))
-    (let (args)
-      (guix-while-search guix-help-parse-option-regexp
-        (let* ((short (match-string-no-properties 1))
-               (name  (match-string-no-properties 2))
-               (arg   (match-string-no-properties 3))
-               (doc   (match-string-no-properties 4))
-               (char  (if short
-                          (elt short 1) ; short option letter
-                        (elt name 2))) ; first letter of the long option
-               ;; If "--foo=bar" or "--foo[=bar]" then it is 'option'.
-               (option? (not (string= "" arg)))
-               ;; If "--foo" or "--foo[=bar]" then it is 'switch'.
-               (switch? (or (string= "" arg)
-                            (eq ?\[ (elt arg 0)))))
-          (push (guix-command-make-argument
-                 :name    name
-                 :char    char
-                 :doc     doc
-                 :switch? switch?
-                 :option? option?)
-                args)))
-      (guix-while-search guix-help-parse-command-regexp
-        (let* ((name (match-string-no-properties 1))
-               (char (elt name 0)))
-          (push (guix-command-make-argument
-                 :name    name
-                 :char    char
-                 :fun     (guix-command-action-name commands name)
-                 :action? t)
-                args)))
-      args)))
-
-(defun guix-command-rest-argument (&optional commands)
-  "Return '--' argument for COMMANDS."
-  (cl-flet ((argument (&rest args)
-              (apply #'guix-command-make-argument
-                     :name "-- " :char ?= :option? t args)))
-    (let ((command (car commands)))
-      (cond
-       ((member command
-                '("archive" "build" "challenge" "edit"
-                  "graph" "lint" "refresh"))
-        (argument :doc "Packages" :fun 'guix-read-package-names-string))
-       ((equal commands '("container" "exec"))
-        (argument :doc "PID Command [Args...]"))
-       ((string= command "download")
-        (argument :doc "URL"))
-       ((string= command "environment")
-        (argument :doc "Command [Args...]" :fun 'read-shell-command))
-       ((string= command "gc")
-        (argument :doc "Paths" :fun 'guix-read-file-name))
-       ((member command '("hash" "system"))
-        (argument :doc "File" :fun 'guix-read-file-name))
-       ((string= command "size")
-        (argument :doc "Package" :fun 'guix-read-package-name))
-       ((equal commands '("import" "nix"))
-        (argument :doc "Nixpkgs Attribute"))
-       ;; Other 'guix import' subcommands, but not 'import' itself.
-       ((and (cdr commands)
-             (string= command "import"))
-        (argument :doc "Package name"))))))
-
-(defvar guix-command-additional-arguments
-  `((("environment")
-     ,(guix-command-make-argument
-       :name "++packages " :char ?p :option? t
-       :doc "build inputs of the specified packages"
-       :fun 'guix-read-package-names-string)))
-  "Alist of guix commands and additional arguments for them.
-These are 'fake' arguments that are not presented in 'guix' shell
-commands.")
-
-(defun guix-command-additional-arguments (&optional commands)
-  "Return additional arguments for COMMANDS."
-  (let ((rest-arg (guix-command-rest-argument commands)))
-    (append (guix-assoc-value guix-command-additional-arguments
-                              commands)
-            (and rest-arg (list rest-arg)))))
-
-;; Ideally only `guix-command-arguments' function should exist with the
-;; contents of `guix-command-all-arguments', but we need to make a
-;; special case for `guix-command-complex-with-shared-arguments' commands.
-
-(defun guix-command-all-arguments (&optional commands)
-  "Return list of all arguments for 'guix COMMANDS ...'."
-  (let ((parsed (guix-command-parse-arguments commands)))
-    (append (guix-command-improve-arguments parsed commands)
-            (guix-command-additional-arguments commands))))
-
-(guix-memoized-defalias guix-command-all-arguments-memoize
-  guix-command-all-arguments)
-
-(defun guix-command-arguments (&optional commands)
-  "Return list of arguments for 'guix COMMANDS ...'."
-  (let ((command (car commands)))
-    (if (member command
-                guix-command-complex-with-shared-arguments)
-        ;; Take actions only for 'guix system', and switches+options for
-        ;; 'guix system foo'.
-        (funcall (if (null (cdr commands))
-                     #'cl-remove-if-not
-                   #'cl-remove-if)
-                 #'guix-command-argument-action?
-                 (guix-command-all-arguments-memoize (list command)))
-      (guix-command-all-arguments commands))))
-
-(defun guix-command-switch->popup-switch (switch)
-  "Return popup switch from command SWITCH argument."
-  (list (guix-command-argument-char switch)
-        (or (guix-command-argument-doc switch)
-            "Unknown")
-        (guix-command-argument-name switch)))
-
-(defun guix-command-option->popup-option (option)
-  "Return popup option from command OPTION argument."
-  (list (guix-command-argument-char option)
-        (or (guix-command-argument-doc option)
-            "Unknown")
-        (let ((name (guix-command-argument-name option)))
-          (if (string-match-p " \\'" name) ; ends with space
-              name
-            (concat name "=")))
-        (or (guix-command-argument-fun option)
-            'read-from-minibuffer)))
-
-(defun guix-command-action->popup-action (action)
-  "Return popup action from command ACTION argument."
-  (list (guix-command-argument-char action)
-        (or (guix-command-argument-doc action)
-            (guix-command-argument-name action)
-            "Unknown")
-        (guix-command-argument-fun action)))
-
-(defun guix-command-sort-arguments (arguments)
-  "Sort ARGUMENTS by name in alphabetical order."
-  (sort arguments
-        (lambda (a1 a2)
-          (let ((name1 (guix-command-argument-name a1))
-                (name2 (guix-command-argument-name a2)))
-            (cond ((null name1) nil)
-                  ((null name2) t)
-                  (t (string< name1 name2)))))))
-
-(defun guix-command-switches (arguments)
-  "Return switches from ARGUMENTS."
-  (cl-remove-if-not #'guix-command-argument-switch? arguments))
-
-(defun guix-command-options (arguments)
-  "Return options from ARGUMENTS."
-  (cl-remove-if-not #'guix-command-argument-option? arguments))
-
-(defun guix-command-actions (arguments)
-  "Return actions from ARGUMENTS."
-  (cl-remove-if-not #'guix-command-argument-action? arguments))
-
-\f
-;;; Post processing popup arguments
-
-(defvar guix-command-post-processors
-  '(("environment"
-     guix-command-post-process-environment-packages
-     guix-command-post-process-environment-ad-hoc
-     guix-command-post-process-rest-multiple-leave)
-    ("hash"
-     guix-command-post-process-rest-single)
-    ("package"
-     guix-command-post-process-package-args)
-    ("system"
-     guix-command-post-process-rest-single))
-  "Alist of guix commands and functions for post-processing
-a list of arguments returned from popup interface.
-Each function is called on the returned arguments in turn.")
-
-(defvar guix-command-rest-arg-regexp
-  (rx string-start "-- " (group (+ any)))
-  "Regexp to match a string with the 'rest' arguments.")
-
-(defun guix-command-replace-args (args predicate modifier)
-  "Replace arguments matching PREDICATE from ARGS.
-Call MODIFIER on each argument matching PREDICATE and append the
-returned list of strings to the end of ARGS.  Remove the original
-arguments."
-  (let* ((rest nil)
-         (args (mapcar (lambda (arg)
-                         (if (funcall predicate arg)
-                             (progn
-                               (push (funcall modifier arg) rest)
-                               nil)
-                           arg))
-                       args)))
-    (if rest
-        (apply #'append (delq nil args) rest)
-      args)))
-
-(cl-defun guix-command-post-process-matching-args (args regexp
-                                                   &key group split?)
-  "Modify arguments from ARGS matching REGEXP by moving them to
-the end of ARGS list.  If SPLIT? is non-nil, split matching
-arguments into multiple subarguments."
-  (guix-command-replace-args
-   args
-   (lambda (arg)
-     (string-match regexp arg))
-   (lambda (arg)
-     (let ((val (match-string (or group 0) arg))
-           (fun (if split? #'split-string #'list)))
-       (funcall fun val)))))
-
-(defun guix-command-post-process-rest-single (args)
-  "Modify ARGS by moving '-- ARG' argument to the end of ARGS list."
-  (guix-command-post-process-matching-args
-   args guix-command-rest-arg-regexp
-   :group 1))
-
-(defun guix-command-post-process-rest-multiple (args)
-  "Modify ARGS by splitting '-- ARG ...' into multiple subarguments
-and moving them to the end of ARGS list.
-Remove '-- ' string."
-  (guix-command-post-process-matching-args
-   args guix-command-rest-arg-regexp
-   :group 1
-   :split? t))
-
-(defun guix-command-post-process-rest-multiple-leave (args)
-  "Modify ARGS by splitting '-- ARG ...' into multiple subarguments
-and moving them to the end of ARGS list.
-Leave '--' string as a separate argument."
-  (guix-command-post-process-matching-args
-   args guix-command-rest-arg-regexp
-   :split? t))
-
-(defun guix-command-post-process-package-args (args)
-  "Adjust popup ARGS for 'guix package' command."
-  (guix-command-post-process-matching-args
-   args (rx string-start (or "--install " "--remove ") (+ any))
-   :split? t))
-
-(defun guix-command-post-process-environment-packages (args)
-  "Adjust popup ARGS for specified packages of 'guix environment'
-command."
-  (guix-command-post-process-matching-args
-   args (rx string-start "++packages " (group (+ any)))
-   :group 1
-   :split? t))
-
-(defun guix-command-post-process-environment-ad-hoc (args)
-  "Adjust popup ARGS for '--ad-hoc' argument of 'guix environment'
-command."
-  (guix-command-post-process-matching-args
-   args (rx string-start "--ad-hoc " (+ any))
-   :split? t))
-
-(defun guix-command-post-process-args (commands args)
-  "Adjust popup ARGS for guix COMMANDS."
-  (let* ((command (car commands))
-         (processors
-          (append (guix-assoc-value guix-command-post-processors commands)
-                  (guix-assoc-value guix-command-post-processors command))))
-    (guix-modify args
-                 (or processors
-                     (list #'guix-command-post-process-rest-multiple)))))
-
-\f
-;;; 'Execute' actions
-
-(defvar guix-command-default-execute-arguments
-  (list
-   (guix-command-make-argument
-    :name "repl"  :char ?r :doc "Run in Guix REPL")
-   (guix-command-make-argument
-    :name "shell" :char ?s :doc "Run in shell")
-   (guix-command-make-argument
-    :name "copy"  :char ?c :doc "Copy command line"))
-  "List of default 'execute' action arguments.")
-
-(defvar guix-command-additional-execute-arguments
-  (let ((graph-arg (guix-command-make-argument
-                    :name "view" :char ?v :doc "View graph")))
-    `((("build")
-       ,(guix-command-make-argument
-         :name "log" :char ?l :doc "View build log"))
-      (("graph") ,graph-arg)
-      (("size")
-       ,(guix-command-make-argument
-         :name "view" :char ?v :doc "View map"))
-      (("system" "shepherd-graph") ,graph-arg)
-      (("system" "extension-graph") ,graph-arg)))
-  "Alist of guix commands and additional 'execute' action arguments.")
-
-(defun guix-command-execute-arguments (commands)
-  "Return a list of 'execute' action arguments for COMMANDS."
-  (mapcar (lambda (arg)
-            (guix-command-modify-argument arg
-              :action? t
-              :fun (guix-command-action-name
-                    commands (guix-command-argument-name arg))))
-          (append guix-command-default-execute-arguments
-                  (guix-assoc-value
-                   guix-command-additional-execute-arguments commands))))
-
-(defvar guix-command-special-executors
-  '((("environment")
-     ("repl" . guix-run-environment-command-in-repl))
-    (("pull")
-     ("repl" . guix-run-pull-command-in-repl))
-    (("build")
-     ("log" . guix-run-view-build-log))
-    (("graph")
-     ("view" . guix-run-view-graph))
-    (("size")
-     ("view" . guix-run-view-size-map))
-    (("system" "shepherd-graph")
-     ("view" . guix-run-view-graph))
-    (("system" "extension-graph")
-     ("view" . guix-run-view-graph)))
-  "Alist of guix commands and alists of special executers for them.
-See also `guix-command-default-executors'.")
-
-(defvar guix-command-default-executors
-  '(("repl"  . guix-run-command-in-repl)
-    ("shell" . guix-run-command-in-shell)
-    ("copy"  . guix-copy-command-as-kill))
-  "Alist of default executers for action names.")
-
-(defun guix-command-executor (commands name)
-  "Return function to run command line arguments for guix COMMANDS."
-  (or (guix-assoc-value guix-command-special-executors commands name)
-      (guix-assoc-value guix-command-default-executors name)))
-
-(defun guix-run-environment-command-in-repl (args)
-  "Run 'guix ARGS ...' environment command in Guix REPL."
-  ;; As 'guix environment' usually tries to run another process, it may
-  ;; be fun but not wise to run this command in Geiser REPL.
-  (when (or (member "--dry-run" args)
-            (member "--search-paths" args)
-            (when (y-or-n-p
-                   (format "'%s' command will spawn an external process.
-Do you really want to execute this command in Geiser REPL? "
-                           (guix-command-string args)))
-              (message "May \"M-x shell-mode\" be with you!")
-              t))
-    (guix-run-command-in-repl args)))
-
-(defun guix-run-pull-command-in-repl (args)
-  "Run 'guix ARGS ...' pull command in Guix REPL.
-Perform pull-specific actions after operation, see
-`guix-after-pull-hook' and `guix-update-after-pull'."
-  (guix-eval-in-repl
-   (apply #'guix-make-guile-expression 'guix-command args)
-   nil 'pull))
-
-(defun guix-run-view-build-log (args)
-  "Add --log-file to ARGS, run 'guix ARGS ...' build command, and
-open the log file(s)."
-  (let* ((args (if (member "--log-file" args)
-                   args
-                 (cl-list* (car args) "--log-file" (cdr args))))
-         (output (guix-command-output args))
-         (files  (split-string output "\n" t)))
-    (dolist (file files)
-      (guix-build-log-find-file file))))
-
-(defun guix-run-view-graph (args)
-  "Run 'guix ARGS ...' graph command, make the image and open it."
-  (let* ((graph-file (guix-dot-file-name))
-         (dot-args   (guix-dot-arguments graph-file)))
-    (if (guix-eval-read (guix-make-guile-expression
-                         'pipe-guix-output args dot-args))
-        (guix-find-file graph-file)
-      (error "Couldn't create a graph"))))
-
-(defun guix-run-view-size-map (args)
-  "Run 'guix ARGS ...' size command, and open the map file."
-  (let* ((wished-map-file
-          (cl-some (lambda (arg)
-                     (and (string-match "--map-file=\\(.+\\)" arg)
-                          (match-string 1 arg)))
-                   args))
-         (map-file (or wished-map-file (guix-png-file-name)))
-         (args (if wished-map-file
-                   args
-                 (cl-list* (car args)
-                           (concat "--map-file=" map-file)
-                           (cdr args)))))
-    (guix-command-output args)
-    (guix-find-file map-file)))
-
-\f
-;;; Generating popups, actions, etc.
-
-(defmacro guix-command-define-popup-action (name &optional commands)
-  "Define NAME function to generate (if needed) and run popup for COMMANDS."
-  (declare (indent 1) (debug t))
-  (let* ((popup-fun (guix-command-symbol `(,@commands "popup")))
-         (doc (format "Call `%s' (generate it if needed)."
-                      popup-fun)))
-    `(defun ,name (&optional arg)
-       ,doc
-       (interactive "P")
-       (unless (fboundp ',popup-fun)
-         (guix-command-generate-popup ',popup-fun ',commands))
-       (,popup-fun arg))))
-
-(defmacro guix-command-define-execute-action (name executor
-                                                   &optional commands)
-  "Define NAME function to execute the current action for guix COMMANDS.
-EXECUTOR function is called with the current command line arguments."
-  (declare (indent 1) (debug t))
-  (let* ((arguments-fun (guix-command-symbol `(,@commands "arguments")))
-         (doc (format "Call `%s' with the current popup arguments."
-                      executor)))
-    `(defun ,name (&rest args)
-       ,doc
-       (interactive (,arguments-fun))
-       (,executor (append ',commands
-                          (guix-command-post-process-args
-                           ',commands args))))))
-
-(defun guix-command-generate-popup-actions (actions &optional commands)
-  "Generate 'popup' commands from ACTIONS arguments for guix COMMANDS."
-  (dolist (action actions)
-    (let ((fun (guix-command-argument-fun action)))
-      (unless (fboundp fun)
-        (eval `(guix-command-define-popup-action ,fun
-                 ,(append commands
-                          (list (guix-command-argument-name action)))))))))
-
-(defun guix-command-generate-execute-actions (actions &optional commands)
-  "Generate 'execute' commands from ACTIONS arguments for guix COMMANDS."
-  (dolist (action actions)
-    (let ((fun (guix-command-argument-fun action)))
-      (unless (fboundp fun)
-        (eval `(guix-command-define-execute-action ,fun
-                 ,(guix-command-executor
-                   commands (guix-command-argument-name action))
-                 ,commands))))))
-
-(defun guix-command-generate-popup (name &optional commands)
-  "Define NAME popup with 'guix COMMANDS ...' interface."
-  (let* ((command  (car commands))
-         (man-page (concat "guix" (and command (concat "-" command))))
-         (doc      (format "Popup window for '%s' command."
-                           (guix-concat-strings (cons "guix" commands)
-                                                " ")))
-         (args     (guix-command-arguments commands))
-         (switches (guix-command-sort-arguments
-                    (guix-command-switches args)))
-         (options  (guix-command-sort-arguments
-                    (guix-command-options args)))
-         (popup-actions (guix-command-sort-arguments
-                         (guix-command-actions args)))
-         (execute-actions (unless popup-actions
-                            (guix-command-execute-arguments commands)))
-         (actions (or popup-actions execute-actions)))
-    (if popup-actions
-        (guix-command-generate-popup-actions popup-actions commands)
-      (guix-command-generate-execute-actions execute-actions commands))
-    (eval
-     `(guix-define-popup ,name
-        ,doc
-        'guix-commands
-        :man-page ,man-page
-        :switches ',(mapcar #'guix-command-switch->popup-switch switches)
-        :options  ',(mapcar #'guix-command-option->popup-option options)
-        :actions  ',(mapcar #'guix-command-action->popup-action actions)
-        :max-action-columns 4))))
-
-;;;###autoload (autoload 'guix "guix-command" "Popup window for 'guix'." t)
-(guix-command-define-popup-action guix)
-
-(defalias 'guix-edit-action #'guix-edit)
-
-\f
-(defvar guix-command-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "("
-            (group "guix-command-define-"
-                   (or "popup-action"
-                       "execute-action"
-                       "argument-improver"))
-            symbol-end
-            (zero-or-more blank)
-            (zero-or-one
-             (group (one-or-more (or (syntax word) (syntax symbol))))))
-       (1 font-lock-keyword-face)
-       (2 font-lock-function-name-face nil t)))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-command-font-lock-keywords)
-
-(provide 'guix-command)
-
-;;; guix-command.el ends here
diff --git a/emacs/guix-config.el.in b/emacs/guix-config.el.in
deleted file mode 100644
index c09c2fe..0000000
--- a/emacs/guix-config.el.in
+++ /dev/null
@@ -1,44 +0,0 @@
-;;; guix-config.el --- Compile-time configuration of Guix.
-
-;; Copyright © 2015 Mathieu Lirzin <mthl@openmailbox.org>
-;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(defconst guix-config-name "@PACKAGE_NAME@"
-  "Guix full name.")
-
-(defconst guix-config-version "@PACKAGE_VERSION@"
-  "Guix version.")
-
-(defconst guix-config-emacs-interface-directory
-  (replace-regexp-in-string "${prefix}" "@prefix@" "@emacsuidir@"))
-
-(defconst guix-config-state-directory
-  ;; This must match `NIX_STATE_DIR' as defined in `nix/local.mk'.
-  (or (getenv "NIX_STATE_DIR") "@guix_localstatedir@/guix"))
-
-(defconst guix-config-guile-program "@GUILE@"
-  "Name of the 'guile' executable defined at configure time.")
-
-(defconst guix-config-dot-program "@DOT_USER_PROGRAM@"
-  "Name of the 'dot' executable defined at configure time.")
-
-(provide 'guix-config)
-
-;;; guix-config.el ends here
diff --git a/emacs/guix-devel.el b/emacs/guix-devel.el
deleted file mode 100644
index b71670c..0000000
--- a/emacs/guix-devel.el
+++ /dev/null
@@ -1,382 +0,0 @@
-;;; guix-devel.el --- Development tools   -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides commands useful for developing Guix (or even
-;; arbitrary Guile code) with Geiser.
-
-;;; Code:
-
-(require 'lisp-mode)
-(require 'guix-guile)
-(require 'guix-geiser)
-(require 'guix-utils)
-(require 'guix-base)
-
-(defgroup guix-devel nil
-  "Settings for Guix development utils."
-  :group 'guix)
-
-(defgroup guix-devel-faces nil
-  "Faces for `guix-devel-mode'."
-  :group 'guix-devel
-  :group 'guix-faces)
-
-(defface guix-devel-modify-phases-keyword
-  '((t :inherit font-lock-preprocessor-face))
-  "Face for a `modify-phases' keyword ('delete', 'replace', etc.)."
-  :group 'guix-devel-faces)
-
-(defface guix-devel-gexp-symbol
-  '((t :inherit font-lock-keyword-face))
-  "Face for gexp symbols ('#~', '#$', etc.).
-See Info node `(guix) G-Expressions'."
-  :group 'guix-devel-faces)
-
-(defcustom guix-devel-activate-mode t
-  "If non-nil, then `guix-devel-mode' is automatically activated
-in Scheme buffers."
-  :type 'boolean
-  :group 'guix-devel)
-
-(defun guix-devel-use-modules (&rest modules)
-  "Use guile MODULES."
-  (apply #'guix-geiser-call "use-modules" modules))
-
-(defun guix-devel-use-module (&optional module)
-  "Use guile MODULE in the current Geiser REPL.
-MODULE is a string with the module name - e.g., \"(ice-9 match)\".
-Interactively, use the module defined by the current scheme file."
-  (interactive (list (guix-guile-current-module)))
-  (guix-devel-use-modules module)
-  (message "Using %s module." module))
-
-(defun guix-devel-copy-module-as-kill ()
-  "Put the name of the current guile module into `kill-ring'."
-  (interactive)
-  (guix-copy-as-kill (guix-guile-current-module)))
-
-(defun guix-devel-setup-repl (&optional repl)
-  "Setup REPL for using `guix-devel-...' commands."
-  (guix-devel-use-modules "(guix monad-repl)"
-                          "(guix scripts)"
-                          "(guix store)"
-                          "(guix ui)")
-  ;; Without this workaround, the warning/build output disappears.  See
-  ;; <https://github.com/jaor/geiser/issues/83> for details.
-  (guix-geiser-eval-in-repl-synchronously
-   "(begin
-      (guix-warning-port (current-warning-port))
-      (current-build-output-port (current-error-port)))"
-   repl 'no-history 'no-display))
-
-(defvar guix-devel-repl-processes nil
-  "List of REPL processes configured by `guix-devel-setup-repl'.")
-
-(defun guix-devel-setup-repl-maybe (&optional repl)
-  "Setup (if needed) REPL for using `guix-devel-...' commands."
-  (let ((process (get-buffer-process (or repl (guix-geiser-repl)))))
-    (when (and process
-               (not (memq process guix-devel-repl-processes)))
-      (guix-devel-setup-repl repl)
-      (push process guix-devel-repl-processes))))
-
-(defmacro guix-devel-with-definition (def-var &rest body)
-  "Run BODY with the current guile definition bound to DEF-VAR.
-Bind DEF-VAR variable to the name of the current top-level
-definition, setup the current REPL, use the current module, and
-run BODY."
-  (declare (indent 1) (debug (symbolp body)))
-  `(let ((,def-var (guix-guile-current-definition)))
-     (guix-devel-setup-repl-maybe)
-     (guix-devel-use-modules (guix-guile-current-module))
-     ,@body))
-
-(defun guix-devel-build-package-definition ()
-  "Build a package defined by the current top-level variable definition."
-  (interactive)
-  (guix-devel-with-definition def
-    (when (or (not guix-operation-confirm)
-              (guix-operation-prompt (format "Build '%s'?" def)))
-      (guix-geiser-eval-in-repl
-       (concat ",run-in-store "
-               (guix-guile-make-call-expression
-                "build-package" def
-                "#:use-substitutes?" (guix-guile-boolean
-                                      guix-use-substitutes)
-                "#:dry-run?" (guix-guile-boolean guix-dry-run)))))))
-
-(defun guix-devel-build-package-source ()
-  "Build the source of the current package definition."
-  (interactive)
-  (guix-devel-with-definition def
-    (when (or (not guix-operation-confirm)
-              (guix-operation-prompt
-               (format "Build '%s' package source?" def)))
-      (guix-geiser-eval-in-repl
-       (concat ",run-in-store "
-               (guix-guile-make-call-expression
-                "build-package-source" def
-                "#:use-substitutes?" (guix-guile-boolean
-                                      guix-use-substitutes)
-                "#:dry-run?" (guix-guile-boolean guix-dry-run)))))))
-
-(defun guix-devel-lint-package ()
-  "Check the current package.
-See Info node `(guix) Invoking guix lint' for details."
-  (interactive)
-  (guix-devel-with-definition def
-    (guix-devel-use-modules "(guix scripts lint)")
-    (when (or (not guix-operation-confirm)
-              (y-or-n-p (format "Lint '%s' package?" def)))
-      (guix-geiser-eval-in-repl
-       (format "(run-checkers %s)" def)))))
-
-\f
-;;; Font-lock
-
-(defvar guix-devel-modify-phases-keyword-regexp
-  (rx (+ word))
-  "Regexp for a 'modify-phases' keyword ('delete', 'replace', etc.).")
-
-(defun guix-devel-modify-phases-font-lock-matcher (limit)
-  "Find a 'modify-phases' keyword.
-This function is used as a MATCHER for `font-lock-keywords'."
-  (ignore-errors
-    (down-list)
-    (or (re-search-forward guix-devel-modify-phases-keyword-regexp
-                           limit t)
-        (set-match-data nil))
-    (up-list)
-    t))
-
-(defun guix-devel-modify-phases-font-lock-pre ()
-  "Skip the next sexp, and return the end point of the current list.
-This function is used as a PRE-MATCH-FORM for `font-lock-keywords'
-to find 'modify-phases' keywords."
-  (let ((in-comment? (nth 4 (syntax-ppss))))
-    ;; If 'modify-phases' is commented, do not try to search for its
-    ;; keywords.
-    (unless in-comment?
-      (ignore-errors (forward-sexp))
-      (save-excursion (up-list) (point)))))
-
-(defconst guix-devel-keywords
-  '("call-with-compressed-output-port"
-    "call-with-container"
-    "call-with-decompressed-port"
-    "call-with-derivation-narinfo"
-    "call-with-derivation-substitute"
-    "call-with-error-handling"
-    "call-with-temporary-directory"
-    "call-with-temporary-output-file"
-    "define-enumerate-type"
-    "define-gexp-compiler"
-    "define-lift"
-    "define-monad"
-    "define-operation"
-    "define-record-type*"
-    "emacs-substitute-sexps"
-    "emacs-substitute-variables"
-    "mbegin"
-    "mlet"
-    "mlet*"
-    "modify-services"
-    "munless"
-    "mwhen"
-    "run-with-state"
-    "run-with-store"
-    "signature-case"
-    "substitute*"
-    "substitute-keyword-arguments"
-    "test-assertm"
-    "use-package-modules"
-    "use-service-modules"
-    "use-system-modules"
-    "with-atomic-file-output"
-    "with-atomic-file-replacement"
-    "with-derivation-narinfo"
-    "with-derivation-substitute"
-    "with-directory-excursion"
-    "with-error-handling"
-    "with-imported-modules"
-    "with-monad"
-    "with-mutex"
-    "with-store"))
-
-(defvar guix-devel-font-lock-keywords
-  `((,(rx (or "#~" "#$" "#$@" "#+" "#+@")) .
-     'guix-devel-gexp-symbol)
-    (,(guix-guile-keyword-regexp (regexp-opt guix-devel-keywords))
-     (1 'font-lock-keyword-face))
-    (,(guix-guile-keyword-regexp "modify-phases")
-     (1 'font-lock-keyword-face)
-     (guix-devel-modify-phases-font-lock-matcher
-      (guix-devel-modify-phases-font-lock-pre)
-      nil
-      (0 'guix-devel-modify-phases-keyword nil t))))
-  "A list of `font-lock-keywords' for `guix-devel-mode'.")
-
-\f
-;;; Indentation
-
-(defmacro guix-devel-scheme-indent (&rest rules)
-  "Set `scheme-indent-function' according to RULES.
-Each rule should have a form (SYMBOL VALUE).  See `put' for details."
-  (declare (indent 0))
-  `(progn
-     ,@(mapcar (lambda (rule)
-                 `(put ',(car rule) 'scheme-indent-function ,(cadr rule)))
-               rules)))
-
-(defun guix-devel-indent-package (state indent-point normal-indent)
-  "Indentation rule for 'package' form."
-  (let* ((package-eol (line-end-position))
-         (count (if (and (ignore-errors (down-list) t)
-                         (< (point) package-eol)
-                         (looking-at "inherit\\>"))
-                    1
-                  0)))
-    (lisp-indent-specform count state indent-point normal-indent)))
-
-(defun guix-devel-indent-modify-phases-keyword (count)
-  "Return indentation function for 'modify-phases' keywords."
-  (lambda (state indent-point normal-indent)
-    (when (ignore-errors
-            (goto-char (nth 1 state))   ; start of keyword sexp
-            (backward-up-list)
-            (looking-at "(modify-phases\\>"))
-      (lisp-indent-specform count state indent-point normal-indent))))
-
-(defalias 'guix-devel-indent-modify-phases-keyword-1
-  (guix-devel-indent-modify-phases-keyword 1))
-(defalias 'guix-devel-indent-modify-phases-keyword-2
-  (guix-devel-indent-modify-phases-keyword 2))
-
-(guix-devel-scheme-indent
-  (bag 0)
-  (build-system 0)
-  (call-with-compressed-output-port 2)
-  (call-with-container 1)
-  (call-with-decompressed-port 2)
-  (call-with-error-handling 0)
-  (container-excursion 1)
-  (emacs-batch-edit-file 1)
-  (emacs-batch-eval 0)
-  (emacs-substitute-sexps 1)
-  (emacs-substitute-variables 1)
-  (file-system 0)
-  (graft 0)
-  (manifest-entry 0)
-  (manifest-pattern 0)
-  (mbegin 1)
-  (mlet 2)
-  (mlet* 2)
-  (modify-phases 1)
-  (modify-services 1)
-  (munless 1)
-  (mwhen 1)
-  (operating-system 0)
-  (origin 0)
-  (package 'guix-devel-indent-package)
-  (run-with-state 1)
-  (run-with-store 1)
-  (signature-case 1)
-  (substitute* 1)
-  (substitute-keyword-arguments 1)
-  (test-assertm 1)
-  (with-atomic-file-output 1)
-  (with-derivation-narinfo 1)
-  (with-derivation-substitute 2)
-  (with-directory-excursion 1)
-  (with-error-handling 0)
-  (with-imported-modules 1)
-  (with-monad 1)
-  (with-mutex 1)
-  (with-store 1)
-  (wrap-program 1)
-
-  ;; 'modify-phases' keywords:
-  (replace    'guix-devel-indent-modify-phases-keyword-1)
-  (add-after  'guix-devel-indent-modify-phases-keyword-2)
-  (add-before 'guix-devel-indent-modify-phases-keyword-2))
-
-\f
-(defvar guix-devel-keys-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "b") 'guix-devel-build-package-definition)
-    (define-key map (kbd "s") 'guix-devel-build-package-source)
-    (define-key map (kbd "l") 'guix-devel-lint-package)
-    (define-key map (kbd "k") 'guix-devel-copy-module-as-kill)
-    (define-key map (kbd "u") 'guix-devel-use-module)
-    map)
-  "Keymap with subkeys for `guix-devel-mode-map'.")
-
-(defvar guix-devel-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c .") guix-devel-keys-map)
-    map)
-  "Keymap for `guix-devel-mode'.")
-
-;;;###autoload
-(define-minor-mode guix-devel-mode
-  "Minor mode for `scheme-mode' buffers.
-
-With a prefix argument ARG, enable the mode if ARG is positive,
-and disable it otherwise.  If called from Lisp, enable the mode
-if ARG is omitted or nil.
-
-When Guix Devel mode is enabled, it provides the following key
-bindings:
-
-\\{guix-devel-mode-map}"
-  :init-value nil
-  :lighter " Guix"
-  :keymap guix-devel-mode-map
-  (if guix-devel-mode
-      (progn
-        (setq-local font-lock-multiline t)
-        (font-lock-add-keywords nil guix-devel-font-lock-keywords))
-    (setq-local font-lock-multiline nil)
-    (font-lock-remove-keywords nil guix-devel-font-lock-keywords))
-  (when font-lock-mode
-    (font-lock-fontify-buffer)))
-
-;;;###autoload
-(defun guix-devel-activate-mode-maybe ()
-  "Activate `guix-devel-mode' depending on
-`guix-devel-activate-mode' variable."
-  (when guix-devel-activate-mode
-    (guix-devel-mode)))
-
-;;;###autoload
-(add-hook 'scheme-mode-hook 'guix-devel-activate-mode-maybe)
-
-\f
-(defvar guix-devel-emacs-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group "guix-devel-with-definition") symbol-end) . 1))))
-
-(font-lock-add-keywords 'emacs-lisp-mode
-                        guix-devel-emacs-font-lock-keywords)
-
-(provide 'guix-devel)
-
-;;; guix-devel.el ends here
diff --git a/emacs/guix-entry.el b/emacs/guix-entry.el
deleted file mode 100644
index 5eed2ed..0000000
--- a/emacs/guix-entry.el
+++ /dev/null
@@ -1,59 +0,0 @@
-;;; guix-entry.el --- 'Entry' type  -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides an API for 'entry' type which is just an alist of
-;; KEY/VALUE pairs (KEY should be a symbol) with the required 'id' KEY.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-utils)
-
-(defalias 'guix-entry-value #'guix-assq-value)
-
-(defun guix-entry-id (entry)
-  "Return ENTRY ID."
-  (guix-entry-value entry 'id))
-
-(defun guix-entry-by-id (id entries)
-  "Return an entry from ENTRIES by its ID."
-  (cl-find-if (lambda (entry)
-                (equal (guix-entry-id entry) id))
-              entries))
-
-(defun guix-entries-by-ids (ids entries)
-  "Return entries with IDS (a list of identifiers) from ENTRIES."
-  (cl-remove-if-not (lambda (entry)
-                      (member (guix-entry-id entry) ids))
-                    entries))
-
-(defun guix-replace-entry (id new-entry entries)
-  "Replace an entry with ID from ENTRIES by NEW-ENTRY.
-Return a list of entries with the replaced entry."
-  (cl-substitute-if new-entry
-                    (lambda (entry)
-                      (equal id (guix-entry-id entry)))
-                    entries
-                    :count 1))
-
-(provide 'guix-entry)
-
-;;; guix-entry.el ends here
diff --git a/emacs/guix-external.el b/emacs/guix-external.el
deleted file mode 100644
index f571ffd..0000000
--- a/emacs/guix-external.el
+++ /dev/null
@@ -1,88 +0,0 @@
-;;; guix-external.el --- External programs  -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides auxiliary code for running external programs.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-config)
-
-(defgroup guix-external nil
-  "Settings for external programs."
-  :group 'guix)
-
-(defcustom guix-guile-program guix-config-guile-program
-  "Name of the 'guile' executable used for Guix REPL.
-May be either a string (the name of the executable) or a list of
-strings of the form:
-
-  (NAME . ARGS)
-
-Where ARGS is a list of arguments to the guile program."
-  :type 'string
-  :group 'guix-external)
-
-(defcustom guix-dot-program
-  (if (file-name-absolute-p guix-config-dot-program)
-      guix-config-dot-program
-    (executable-find "dot"))
-  "Name of the 'dot' executable."
-  :type 'string
-  :group 'guix-external)
-
-(defcustom guix-dot-default-arguments
-  '("-Tpng")
-  "Default arguments for 'dot' program."
-  :type '(repeat string)
-  :group 'guix-external)
-
-(defcustom guix-dot-file-name-function #'guix-png-file-name
-  "Function used to define a file name of a temporary 'dot' file.
-The function is called without arguments."
-  :type '(choice (function-item guix-png-file-name)
-                 (function :tag "Other function"))
-  :group 'guix-external)
-
-(defun guix-dot-arguments (output-file &rest args)
-  "Return a list of dot arguments for writing a graph into OUTPUT-FILE.
-If ARGS is nil, use `guix-dot-default-arguments'."
-  (or guix-dot-program
-      (error (concat "Couldn't find 'dot'.\n"
-                     "Set guix-dot-program to a proper value")))
-  (cl-list* guix-dot-program
-            (concat "-o" output-file)
-            (or args guix-dot-default-arguments)))
-
-(defun guix-dot-file-name ()
-  "Call `guix-dot-file-name-function'."
-  (funcall guix-dot-file-name-function))
-
-(defun guix-png-file-name ()
-  "Return '.png' file name in the `temporary-file-directory'."
-  (concat (make-temp-name
-           (concat (file-name-as-directory temporary-file-directory)
-                   "guix-emacs-graph-"))
-          ".png"))
-
-(provide 'guix-external)
-
-;;; guix-external.el ends here
diff --git a/emacs/guix-geiser.el b/emacs/guix-geiser.el
deleted file mode 100644
index 833f5bb..0000000
--- a/emacs/guix-geiser.el
+++ /dev/null
@@ -1,126 +0,0 @@
-;;; guix-geiser.el --- Interacting with Geiser   -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides functions to evaluate guile code using Geiser.
-
-;;; Code:
-
-(require 'geiser-mode)
-(require 'guix-guile)
-
-(defun guix-geiser-repl ()
-  "Return the current Geiser REPL."
-  (or geiser-repl--repl
-      (geiser-repl--repl/impl 'guile)
-      (error "Geiser REPL not found")))
-
-(defun guix-geiser-eval (str &optional repl)
-  "Evaluate STR with guile expression using Geiser REPL.
-If REPL is nil, use the current Geiser REPL.
-Return a list of strings with result values of evaluation."
-  (with-current-buffer (or repl (guix-geiser-repl))
-    (let ((res (geiser-eval--send/wait `(:eval (:scm ,str)))))
-      (if (geiser-eval--retort-error res)
-          (error "Error in evaluating guile expression: %s"
-                 (geiser-eval--retort-output res))
-        (cdr (assq 'result res))))))
-
-(defun guix-geiser-eval-read (str &optional repl)
-  "Evaluate STR with guile expression using Geiser REPL.
-Return elisp expression of the first result value of evaluation."
-  ;; The goal is to convert a string with scheme expression into elisp
-  ;; expression.
-  (let ((result (car (guix-geiser-eval str repl))))
-    (cond
-     ((or (string= result "#f")
-          (string= result "#<unspecified>"))
-      nil)
-     ((string= result "#t")
-      t)
-     (t
-      (read (replace-regexp-in-string
-             "[ (]\\(#f\\)" "nil"
-             (replace-regexp-in-string
-              "[ (]\\(#t\\)" "t"
-              result
-              nil nil 1)
-             nil nil 1))))))
-
-(defun guix-repl-send (cmd &optional save-history)
-  "Send CMD input string to the current REPL buffer.
-This is the same as `geiser-repl--send', but with SAVE-HISTORY
-argument.  If SAVE-HISTORY is non-nil, save CMD in the REPL
-history."
-  (when (and cmd (eq major-mode 'geiser-repl-mode))
-    (geiser-repl--prepare-send)
-    (goto-char (point-max))
-    (comint-kill-input)
-    (insert cmd)
-    (let ((comint-input-filter (if save-history
-                                   comint-input-filter
-                                 'ignore)))
-      (comint-send-input nil t))))
-
-(defun guix-geiser-eval-in-repl (str &optional repl no-history no-display)
-  "Switch to Geiser REPL and evaluate STR with guile expression there.
-If NO-HISTORY is non-nil, do not save STR in the REPL history.
-If NO-DISPLAY is non-nil, do not switch to the REPL buffer."
-  (let ((repl (or repl (guix-geiser-repl))))
-    (with-current-buffer repl
-      ;; XXX Since Geiser 0.8, `geiser-repl--send' has SAVE-HISTORY
-      ;; argument, so use this function eventually and remove
-      ;; `guix-repl-send'.
-      (guix-repl-send str (not no-history)))
-    (unless no-display
-      (geiser-repl--switch-to-buffer repl))))
-
-(defun guix-geiser-eval-in-repl-synchronously (str &optional repl
-                                                   no-history no-display)
-  "Evaluate STR in Geiser REPL synchronously, i.e. wait until the
-REPL operation will be finished.
-See `guix-geiser-eval-in-repl' for the meaning of arguments."
-  (let* ((repl (if repl (get-buffer repl) (guix-geiser-repl)))
-         (running? nil)
-         (filter (lambda (output)
-                   (setq running?
-                         (and (get-buffer-process repl)
-                              (not (guix-guile-prompt? output))))))
-         (comint-output-filter-functions
-          (cons filter comint-output-filter-functions)))
-    (guix-geiser-eval-in-repl str repl no-history no-display)
-    (while running?
-      (sleep-for 0.1))))
-
-(defun guix-geiser-call (proc &rest args)
-  "Call (PROC ARGS ...) synchronously using the current Geiser REPL.
-PROC and ARGS should be strings."
-  (guix-geiser-eval
-   (apply #'guix-guile-make-call-expression proc args)))
-
-(defun guix-geiser-call-in-repl (proc &rest args)
-  "Call (PROC ARGS ...) in the current Geiser REPL.
-PROC and ARGS should be strings."
-  (guix-geiser-eval-in-repl
-   (apply #'guix-guile-make-call-expression proc args)))
-
-(provide 'guix-geiser)
-
-;;; guix-geiser.el ends here
diff --git a/emacs/guix-guile.el b/emacs/guix-guile.el
deleted file mode 100644
index 792f825..0000000
--- a/emacs/guix-guile.el
+++ /dev/null
@@ -1,98 +0,0 @@
-;;; guix-guile.el --- Auxiliary tools for working with guile code   -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides functions for parsing guile code, making guile
-;; expressions, etc.
-
-;;; Code:
-
-(require 'geiser-guile)
-
-(defvar guix-guile-definition-regexp
-  (rx bol "(define"
-      (zero-or-one "*")
-      (zero-or-one "-public")
-      (one-or-more space)
-      (zero-or-one "(")
-      (group (one-or-more (or word (syntax symbol)))))
-  "Regexp used to find the guile definition.")
-
-(defun guix-guile-current-definition ()
-  "Return string with name of the current top-level guile definition."
-  (save-excursion
-    (beginning-of-defun)
-    (if (looking-at guix-guile-definition-regexp)
-        (match-string-no-properties 1)
-      (error "Couldn't find the current definition"))))
-
-(defun guix-guile-current-module ()
-  "Return a string with the current guile module.
-Return nil, if current buffer does not define a module."
-  ;; Modified version of `geiser-guile--get-module'.
-  (save-excursion
-    (geiser-syntax--pop-to-top)
-    (when (or (re-search-backward geiser-guile--module-re nil t)
-              (looking-at geiser-guile--library-re)
-              (re-search-forward geiser-guile--module-re nil t))
-      (match-string-no-properties 1))))
-
-(defun guix-guile-boolean (arg)
-  "Return a string with guile boolean value.
-Transform elisp ARG (nil or non-nil) to the guile boolean (#f or #t)."
-  (if arg "#t" "#f"))
-
-(defun guix-guile-keyword-regexp (keyword)
-  "Return regexp to find guile KEYWORD."
-  (format "(\\(%s\\)\\_>" keyword))
-
-(defun guix-guile-make-call-expression (proc &rest args)
-  "Return \"(PROC ARGS ...)\" string.
-PROC and ARGS should be strings."
-  (format "(%s %s)"
-          proc
-          (mapconcat #'identity args " ")))
-
-(defun guix-make-guile-expression (fun &rest args)
-  "Return string containing a guile expression for calling FUN with ARGS."
-  (format "(%S %s)" fun
-          (mapconcat
-           (lambda (arg)
-             (cond
-              ((null arg) "'()")
-              ((or (eq arg t)
-                   ;; An ugly hack to separate 'false' from nil.
-                   (equal arg 'f)
-                   (keywordp arg))
-               (concat "#" (prin1-to-string arg t)))
-              ((or (symbolp arg) (listp arg))
-               (concat "'" (prin1-to-string arg)))
-              (t (prin1-to-string arg))))
-           args
-           " ")))
-
-(defun guix-guile-prompt? (string)
-  "Return non-nil, if STRING contains a Guile prompt."
-  (or (string-match-p geiser-guile--prompt-regexp string)
-      (string-match-p geiser-guile--debugger-prompt-regexp string)))
-
-(provide 'guix-guile)
-
-;;; guix-guile.el ends here
diff --git a/emacs/guix-help-vars.el b/emacs/guix-help-vars.el
deleted file mode 100644
index 8117d28..0000000
--- a/emacs/guix-help-vars.el
+++ /dev/null
@@ -1,108 +0,0 @@
-;;; guix-help-vars.el --- Variables related to --help output
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides regular expressions to parse various "guix
-;; ... --help" outputs and lists of non-receivable items (system types,
-;; hash formats, etc.).
-
-;;; Code:
-
-\f
-;;; Regexps for parsing "guix ..." outputs
-
-(defvar guix-help-parse-option-regexp
-  (rx bol "  "
-      (zero-or-one (group "-" (not (any "- ")))
-                   ",")
-      (one-or-more " ")
-      (group "--" (one-or-more (or wordchar "-")))
-      (group (zero-or-one "[")
-             (zero-or-one "="))
-      (zero-or-more (not space))
-      (one-or-more space)
-      (group (one-or-more any)))
-  "Common regexp used to find command options.")
-
-(defvar guix-help-parse-command-regexp
-  (rx bol "   "
-      (group wordchar (one-or-more (or wordchar "-"))))
-  "Regexp used to find guix commands.
-'Command' means any option not prefixed with '-'.  For example,
-guix subcommand, system action, importer, etc.")
-
-(defvar guix-help-parse-long-option-regexp
-  (rx (or "  " ", ")
-      (group "--" (one-or-more (or wordchar "-"))
-             (zero-or-one "=")))
-  "Regexp used to find long options.")
-
-(defvar guix-help-parse-short-option-regexp
-  (rx bol (one-or-more blank)
-      "-" (group (not (any "- "))))
-  "Regexp used to find short options.")
-
-(defvar guix-help-parse-package-regexp
-  (rx bol (group (one-or-more (not blank))))
-  "Regexp used to find names of the packages.")
-
-(defvar guix-help-parse-list-regexp
-  (rx bol (zero-or-more blank) "- "
-      (group (one-or-more (or wordchar "-"))))
-  "Regexp used to find various lists (lint checkers, graph types).")
-
-(defvar guix-help-parse-regexp-group 1
-  "Parenthesized expression of regexps used to find commands and
-options.")
-
-\f
-;;; Non-receivable lists of system types, hash formats, etc.
-
-(defvar guix-help-system-types
-  '("x86_64-linux" "i686-linux" "armhf-linux" "mips64el-linux")
-  "List of supported systems.")
-
-(defvar guix-help-source-types
-  '("package" "all" "transitive")
-  "List of supported sources types.")
-
-(defvar guix-help-hash-formats
-  '("nix-base32" "base32" "base16" "hex" "hexadecimal")
-  "List of supported hash formats.")
-
-(defvar guix-help-refresh-subsets
-  '("core" "non-core")
-  "List of supported 'refresh' subsets.")
-
-(defvar guix-help-key-policies
-  '("interactive" "always" "never")
-  "List of supported key download policies.")
-
-(defvar guix-help-verify-options
-  '("repair" "contents")
-  "List of supported 'verify' options")
-
-(defvar guix-help-elpa-archives
-  '("gnu" "melpa" "melpa-stable")
-  "List of supported ELPA archives.")
-
-(provide 'guix-help-vars)
-
-;;; guix-help-vars.el ends here
diff --git a/emacs/guix-helper.scm.in b/emacs/guix-helper.scm.in
deleted file mode 100644
index 0bbd36b..0000000
--- a/emacs/guix-helper.scm.in
+++ /dev/null
@@ -1,65 +0,0 @@
-;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014 Alex Kost <alezost@gmail.com>
-;;;
-;;; This file is part of GNU Guix.
-;;;
-;;; GNU Guix is free software; you can redistribute it and/or modify it
-;;; under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 3 of the License, or (at
-;;; your option) any later version.
-;;;
-;;; GNU Guix is distributed in the hope that it will be useful, but
-;;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This is an auxiliary file for the Emacs UI.  It is used to add Guix
-;; directories to path variables and to load the main code.
-
-;;; Code:
-
-(use-modules (ice-9 regex)
-             (srfi srfi-26))
-
-(define %guix-dir)
-
-;; The code is taken from ‘guix’ executable script
-(define (set-paths!)
-  (define-syntax-rule (push! elt v) (set! v (cons elt v)))
-
-  (define config-lookup
-    (let ((config '(("prefix"         . "@prefix@")
-                    ("guilemoduledir" . "@guilemoduledir@")))
-          (var-ref-regexp (make-regexp "\\$\\{([a-z]+)\\}")))
-      (define (expand-var-ref match)
-        (lookup (match:substring match 1)))
-      (define (expand str)
-        (regexp-substitute/global #f var-ref-regexp str
-                                  'pre expand-var-ref 'post))
-      (define (lookup name)
-        (expand (assoc-ref config name)))
-      lookup))
-
-  (let ((module-dir (config-lookup "guilemoduledir"))
-        (updates-dir (and=> (or (getenv "XDG_CONFIG_HOME")
-                                (and=> (getenv "HOME")
-                                       (cut string-append <> "/.config")))
-                            (cut string-append <> "/guix/latest"))))
-    (push! module-dir %load-path)
-    (push! module-dir %load-compiled-path)
-    (if (and updates-dir (file-exists? updates-dir))
-        (begin
-          (set! %guix-dir updates-dir)
-          (push! updates-dir %load-path)
-          (push! updates-dir %load-compiled-path))
-        (set! %guix-dir module-dir))))
-
-(set-paths!)
-
-(load-from-path "guix-main")
-
diff --git a/emacs/guix-history.el b/emacs/guix-history.el
deleted file mode 100644
index 5d301a6..0000000
--- a/emacs/guix-history.el
+++ /dev/null
@@ -1,92 +0,0 @@
-;;; guix-history.el --- History of buffer information
-
-;; Copyright © 2014 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides support for history of buffers similar to the
-;; history of a `help-mode' buffer.
-
-;;; Code:
-
-(require 'cl-macs)
-
-(defvar-local guix-history-stack-item nil
-  "Current item of the history.
-A list of the form (FUNCTION [ARGS ...]).
-The item is used by calling (apply FUNCTION ARGS).")
-(put 'guix-history-stack-item 'permanent-local t)
-
-(defvar-local guix-history-back-stack nil
-  "Stack (list) of visited items.
-Each element of the list has a form of `guix-history-stack-item'.")
-(put 'guix-history-back-stack 'permanent-local t)
-
-(defvar-local guix-history-forward-stack nil
-  "Stack (list) of items visited with `guix-history-back'.
-Each element of the list has a form of `guix-history-stack-item'.")
-(put 'guix-history-forward-stack 'permanent-local t)
-
-(defvar guix-history-size 0
-  "Maximum number of items saved in history.
-If 0, the history is disabled.")
-
-(defun guix-history-add (item)
-  "Add ITEM to history."
-  (and guix-history-stack-item
-       (push guix-history-stack-item guix-history-back-stack))
-  (setq guix-history-forward-stack nil
-        guix-history-stack-item item)
-  (when (>= (length guix-history-back-stack)
-            guix-history-size)
-    (setq guix-history-back-stack
-          (cl-loop for elt in guix-history-back-stack
-                   for i from 1 to guix-history-size
-                   collect elt))))
-
-(defun guix-history-replace (item)
-  "Replace current item in history with ITEM."
-  (setq guix-history-stack-item item))
-
-(defun guix-history-goto (item)
-  "Go to the ITEM of history.
-ITEM should have the form of `guix-history-stack-item'."
-  (or (listp item)
-      (error "Wrong value of history element"))
-  (setq guix-history-stack-item item)
-  (apply (car item) (cdr item)))
-
-(defun guix-history-back ()
-  "Go back to the previous element of history in the current buffer."
-  (interactive)
-  (or guix-history-back-stack
-      (user-error "No previous element in history"))
-  (push guix-history-stack-item guix-history-forward-stack)
-  (guix-history-goto (pop guix-history-back-stack)))
-
-(defun guix-history-forward ()
-  "Go forward to the next element of history in the current buffer."
-  (interactive)
-  (or guix-history-forward-stack
-      (user-error "No next element in history"))
-  (push guix-history-stack-item guix-history-back-stack)
-  (guix-history-goto (pop guix-history-forward-stack)))
-
-(provide 'guix-history)
-
-;;; guix-history.el ends here
diff --git a/emacs/guix-hydra-build.el b/emacs/guix-hydra-build.el
deleted file mode 100644
index 232221e..0000000
--- a/emacs/guix-hydra-build.el
+++ /dev/null
@@ -1,362 +0,0 @@
-;;; guix-hydra-build.el --- Interface for Hydra builds  -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides an interface for displaying Hydra builds in
-;; 'list' and 'info' buffers.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-buffer)
-(require 'guix-list)
-(require 'guix-info)
-(require 'guix-hydra)
-(require 'guix-build-log)
-(require 'guix-utils)
-
-(guix-hydra-define-entry-type hydra-build
-  :search-types '((latest . guix-hydra-build-latest-api-url)
-                  (queue  . guix-hydra-build-queue-api-url))
-  :filters '(guix-hydra-build-filter-status)
-  :filter-names '((nixname . name)
-                  (buildstatus . build-status)
-                  (timestamp . time))
-  :filter-boolean-params '(finished busy))
-
-(defun guix-hydra-build-get-display (search-type &rest args)
-  "Search for Hydra builds and show results."
-  (apply #'guix-list-get-display-entries
-         'hydra-build search-type args))
-
-(cl-defun guix-hydra-build-latest-prompt-args (&key project jobset
-                                                    job system)
-  "Prompt for and return a list of 'latest builds' arguments."
-  (let* ((number      (read-number "Number of latest builds: "))
-         (project     (if current-prefix-arg
-                          (guix-hydra-read-project nil project)
-                        project))
-         (jobset      (if current-prefix-arg
-                          (guix-hydra-read-jobset nil jobset)
-                        jobset))
-         (job-or-name (if current-prefix-arg
-                          (guix-hydra-read-job nil job)
-                        job))
-         (job         (and job-or-name
-                           (string-match-p guix-hydra-job-regexp
-                                           job-or-name)
-                           job-or-name))
-         (system      (if (and (not job)
-                               (or current-prefix-arg
-                                   (and job-or-name (not system))))
-                          (if job-or-name
-                              (guix-while-null
-                                (guix-hydra-read-system
-                                 (concat job-or-name ".") system))
-                            (guix-hydra-read-system nil system))
-                        system))
-         (job         (or job
-                          (and job-or-name
-                               (concat job-or-name "." system)))))
-    (list number
-          :project project
-          :jobset  jobset
-          :job     job
-          :system  system)))
-
-(defun guix-hydra-build-view-log (id)
-  "View build log of a hydra build ID."
-  (guix-build-log-find-file (guix-hydra-build-log-url id)))
-
-\f
-;;; Defining URLs
-
-(defun guix-hydra-build-url (id)
-  "Return Hydra URL of a build ID."
-  (guix-hydra-url "build/" (number-to-string id)))
-
-(defun guix-hydra-build-log-url (id)
-  "Return Hydra URL of the log file of a build ID."
-  (concat (guix-hydra-build-url id) "/log/raw"))
-
-(cl-defun guix-hydra-build-latest-api-url
-    (number &key project jobset job system)
-  "Return Hydra API URL to receive latest NUMBER of builds."
-  (guix-hydra-api-url "latestbuilds"
-    `(("nr" . ,number)
-      ("project" . ,project)
-      ("jobset" . ,jobset)
-      ("job" . ,job)
-      ("system" . ,system))))
-
-(defun guix-hydra-build-queue-api-url (number)
-  "Return Hydra API URL to receive the NUMBER of queued builds."
-  (guix-hydra-api-url "queue"
-    `(("nr" . ,number))))
-
-\f
-;;; Filters for processing raw entries
-
-(defun guix-hydra-build-filter-status (entry)
-  "Add 'status' parameter to 'hydra-build' ENTRY."
-  (let ((status (if (guix-entry-value entry 'finished)
-                    (guix-hydra-build-status-number->name
-                     (guix-entry-value entry 'build-status))
-                  (if (guix-entry-value entry 'busy)
-                      'running
-                    'scheduled))))
-    (cons `(status . ,status)
-          entry)))
-
-\f
-;;; Build status
-
-(defface guix-hydra-build-status-running
-  '((t :inherit bold))
-  "Face used if hydra build is not finished."
-  :group 'guix-hydra-build-faces)
-
-(defface guix-hydra-build-status-scheduled
-  '((t))
-  "Face used if hydra build is scheduled."
-  :group 'guix-hydra-build-faces)
-
-(defface guix-hydra-build-status-succeeded
-  '((t :inherit success))
-  "Face used if hydra build succeeded."
-  :group 'guix-hydra-build-faces)
-
-(defface guix-hydra-build-status-cancelled
-  '((t :inherit warning))
-  "Face used if hydra build was cancelled."
-  :group 'guix-hydra-build-faces)
-
-(defface guix-hydra-build-status-failed
-  '((t :inherit error))
-  "Face used if hydra build failed."
-  :group 'guix-hydra-build-faces)
-
-(defvar guix-hydra-build-status-alist
-  '((0 . succeeded)
-    (1 . failed-build)
-    (2 . failed-dependency)
-    (3 . failed-other)
-    (4 . cancelled))
-  "Alist of hydra build status numbers and status names.
-Status numbers are returned by Hydra API, names (symbols) are
-used internally by the elisp code of this package.")
-
-(defun guix-hydra-build-status-number->name (number)
-  "Convert build status number to a name.
-See `guix-hydra-build-status-alist'."
-  (guix-assq-value guix-hydra-build-status-alist number))
-
-(defun guix-hydra-build-status-string (status)
-  "Return a human readable string for build STATUS."
-  (cl-case status
-    (scheduled
-     (guix-get-string "Scheduled" 'guix-hydra-build-status-scheduled))
-    (running
-     (guix-get-string "Running" 'guix-hydra-build-status-running))
-    (succeeded
-     (guix-get-string "Succeeded" 'guix-hydra-build-status-succeeded))
-    (cancelled
-     (guix-get-string "Cancelled" 'guix-hydra-build-status-cancelled))
-    (failed-build
-     (guix-hydra-build-status-fail-string))
-    (failed-dependency
-     (guix-hydra-build-status-fail-string "dependency"))
-    (failed-other
-     (guix-hydra-build-status-fail-string "other"))))
-
-(defun guix-hydra-build-status-fail-string (&optional reason)
-  "Return a string for a failed build."
-  (let ((base (guix-get-string "Failed" 'guix-hydra-build-status-failed)))
-    (if reason
-        (concat base " (" reason ")")
-      base)))
-
-(defun guix-hydra-build-finished? (entry)
-  "Return non-nil, if hydra build was finished."
-  (guix-entry-value entry 'finished))
-
-(defun guix-hydra-build-running? (entry)
-  "Return non-nil, if hydra build is running."
-  (eq (guix-entry-value entry 'status)
-      'running))
-
-(defun guix-hydra-build-scheduled? (entry)
-  "Return non-nil, if hydra build is scheduled."
-  (eq (guix-entry-value entry 'status)
-      'scheduled))
-
-(defun guix-hydra-build-succeeded? (entry)
-  "Return non-nil, if hydra build succeeded."
-  (eq (guix-entry-value entry 'status)
-      'succeeded))
-
-(defun guix-hydra-build-cancelled? (entry)
-  "Return non-nil, if hydra build was cancelled."
-  (eq (guix-entry-value entry 'status)
-      'cancelled))
-
-(defun guix-hydra-build-failed? (entry)
-  "Return non-nil, if hydra build failed."
-  (memq (guix-entry-value entry 'status)
-        '(failed-build failed-dependency failed-other)))
-
-\f
-;;; Hydra build 'info'
-
-(guix-hydra-info-define-interface hydra-build
-  :mode-name "Hydra-Build-Info"
-  :buffer-name "*Guix Hydra Build Info*"
-  :format '((name ignore (simple guix-info-heading))
-            ignore
-            guix-hydra-build-info-insert-url
-            (time     format (time))
-            (status   format guix-hydra-build-info-insert-status)
-            (project  format (format guix-hydra-build-project))
-            (jobset   format (format guix-hydra-build-jobset))
-            (job      format (format guix-hydra-build-job))
-            (system   format (format guix-hydra-build-system))
-            (priority format (format))))
-
-(defface guix-hydra-build-info-project
-  '((t :inherit link))
-  "Face for project names."
-  :group 'guix-hydra-build-info-faces)
-
-(defface guix-hydra-build-info-jobset
-  '((t :inherit link))
-  "Face for jobsets."
-  :group 'guix-hydra-build-info-faces)
-
-(defface guix-hydra-build-info-job
-  '((t :inherit link))
-  "Face for jobs."
-  :group 'guix-hydra-build-info-faces)
-
-(defface guix-hydra-build-info-system
-  '((t :inherit link))
-  "Face for system names."
-  :group 'guix-hydra-build-info-faces)
-
-(defmacro guix-hydra-build-define-button (name)
-  "Define `guix-hydra-build-NAME' button."
-  (let* ((name-str    (symbol-name name))
-         (button-name (intern (concat "guix-hydra-build-" name-str)))
-         (face-name   (intern (concat "guix-hydra-build-info-" name-str)))
-         (keyword     (intern (concat ":" name-str))))
-    `(define-button-type ',button-name
-       :supertype 'guix
-       'face ',face-name
-       'help-echo ,(format "\
-Show latest builds for this %s (with prefix, prompt for all parameters)"
-                           name-str)
-       'action (lambda (btn)
-                 (let ((args (guix-hydra-build-latest-prompt-args
-                              ,keyword (button-label btn))))
-                   (apply #'guix-hydra-build-get-display
-                          'latest args))))))
-
-(guix-hydra-build-define-button project)
-(guix-hydra-build-define-button jobset)
-(guix-hydra-build-define-button job)
-(guix-hydra-build-define-button system)
-
-(defun guix-hydra-build-info-insert-url (entry)
-  "Insert Hydra URL for the build ENTRY."
-  (guix-insert-button (guix-hydra-build-url (guix-entry-id entry))
-                      'guix-url)
-  (when (guix-hydra-build-finished? entry)
-    (guix-info-insert-indent)
-    (guix-info-insert-action-button
-     "Build log"
-     (lambda (btn)
-       (guix-hydra-build-view-log (button-get btn 'id)))
-     "View build log"
-     'id (guix-entry-id entry))))
-
-(defun guix-hydra-build-info-insert-status (status &optional _)
-  "Insert a string with build STATUS."
-  (insert (guix-hydra-build-status-string status)))
-
-\f
-;;; Hydra build 'list'
-
-(guix-hydra-list-define-interface hydra-build
-  :mode-name "Hydra-Build-List"
-  :buffer-name "*Guix Hydra Build List*"
-  :format '((name nil 30 t)
-            (system nil 16 t)
-            (status guix-hydra-build-list-get-status 20 t)
-            (project nil 10 t)
-            (jobset nil 17 t)
-            (time guix-list-get-time 20 t)))
-
-(let ((map guix-hydra-build-list-mode-map))
-  (define-key map (kbd "B") 'guix-hydra-build-list-latest-builds)
-  (define-key map (kbd "L") 'guix-hydra-build-list-view-log))
-
-(defun guix-hydra-build-list-get-status (status &optional _)
-  "Return a string for build STATUS."
-  (guix-hydra-build-status-string status))
-
-(defun guix-hydra-build-list-latest-builds (number &rest args)
-  "Display latest NUMBER of Hydra builds of the current job.
-Interactively, prompt for NUMBER.  With prefix argument, prompt
-for all ARGS."
-  (interactive
-   (let ((entry (guix-list-current-entry)))
-     (guix-hydra-build-latest-prompt-args
-      :project (guix-entry-value entry 'project)
-      :jobset  (guix-entry-value entry 'name)
-      :job     (guix-entry-value entry 'job)
-      :system  (guix-entry-value entry 'system))))
-  (apply #'guix-hydra-latest-builds number args))
-
-(defun guix-hydra-build-list-view-log ()
-  "View build log of the current Hydra build."
-  (interactive)
-  (guix-hydra-build-view-log (guix-list-current-id)))
-
-\f
-;;; Interactive commands
-
-;;;###autoload
-(defun guix-hydra-latest-builds (number &rest args)
-  "Display latest NUMBER of Hydra builds.
-ARGS are the same arguments as for `guix-hydra-build-latest-api-url'.
-Interactively, prompt for NUMBER.  With prefix argument, prompt
-for all ARGS."
-  (interactive (guix-hydra-build-latest-prompt-args))
-  (apply #'guix-hydra-build-get-display
-         'latest number args))
-
-;;;###autoload
-(defun guix-hydra-queued-builds (number)
-  "Display the NUMBER of queued Hydra builds."
-  (interactive "NNumber of queued builds: ")
-  (guix-hydra-build-get-display 'queue number))
-
-(provide 'guix-hydra-build)
-
-;;; guix-hydra-build.el ends here
diff --git a/emacs/guix-hydra-jobset.el b/emacs/guix-hydra-jobset.el
deleted file mode 100644
index a4a55a3..0000000
--- a/emacs/guix-hydra-jobset.el
+++ /dev/null
@@ -1,162 +0,0 @@
-;;; guix-hydra-jobset.el --- Interface for Hydra jobsets  -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides an interface for displaying Hydra jobsets in
-;; 'list' and 'info' buffers.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-buffer)
-(require 'guix-list)
-(require 'guix-info)
-(require 'guix-hydra)
-(require 'guix-hydra-build)
-(require 'guix-utils)
-
-(guix-hydra-define-entry-type hydra-jobset
-  :search-types '((project . guix-hydra-jobset-api-url))
-  :filters '(guix-hydra-jobset-filter-id)
-  :filter-names '((nrscheduled . scheduled)
-                  (nrsucceeded . succeeded)
-                  (nrfailed . failed)
-                  (nrtotal . total)))
-
-(defun guix-hydra-jobset-get-display (search-type &rest args)
-  "Search for Hydra builds and show results."
-  (apply #'guix-list-get-display-entries
-         'hydra-jobset search-type args))
-
-\f
-;;; Defining URLs
-
-(defun guix-hydra-jobset-url (project jobset)
-  "Return Hydra URL of a PROJECT's JOBSET."
-  (guix-hydra-url "jobset/" project "/" jobset))
-
-(defun guix-hydra-jobset-api-url (project)
-  "Return Hydra API URL for jobsets by PROJECT."
-  (guix-hydra-api-url "jobsets"
-    `(("project" . ,project))))
-
-\f
-;;; Filters for processing raw entries
-
-(defun guix-hydra-jobset-filter-id (entry)
-  "Add 'ID' parameter to 'hydra-jobset' ENTRY."
-  (cons `(id . ,(guix-entry-value entry 'name))
-        entry))
-
-\f
-;;; Hydra jobset 'info'
-
-(guix-hydra-info-define-interface hydra-jobset
-  :mode-name "Hydra-Jobset-Info"
-  :buffer-name "*Guix Hydra Jobset Info*"
-  :format '((name ignore (simple guix-info-heading))
-            ignore
-            guix-hydra-jobset-info-insert-url
-            (project   format guix-hydra-jobset-info-insert-project)
-            (scheduled format (format guix-hydra-jobset-info-scheduled))
-            (succeeded format (format guix-hydra-jobset-info-succeeded))
-            (failed    format (format guix-hydra-jobset-info-failed))
-            (total     format (format guix-hydra-jobset-info-total))))
-
-(defface guix-hydra-jobset-info-scheduled
-  '((t))
-  "Face used for the number of scheduled builds."
-  :group 'guix-hydra-jobset-info-faces)
-
-(defface guix-hydra-jobset-info-succeeded
-  '((t :inherit guix-hydra-build-status-succeeded))
-  "Face used for the number of succeeded builds."
-  :group 'guix-hydra-jobset-info-faces)
-
-(defface guix-hydra-jobset-info-failed
-  '((t :inherit guix-hydra-build-status-failed))
-  "Face used for the number of failed builds."
-  :group 'guix-hydra-jobset-info-faces)
-
-(defface guix-hydra-jobset-info-total
-  '((t))
-  "Face used for the total number of builds."
-  :group 'guix-hydra-jobset-info-faces)
-
-(defun guix-hydra-jobset-info-insert-project (project entry)
-  "Insert PROJECT button for the jobset ENTRY."
-  (let ((jobset (guix-entry-value entry 'name)))
-    (guix-insert-button
-     project 'guix-hydra-build-project
-     'action (lambda (btn)
-               (let ((args (guix-hydra-build-latest-prompt-args
-                            :project (button-get btn 'project)
-                            :jobset  (button-get btn 'jobset))))
-                 (apply #'guix-hydra-build-get-display
-                        'latest args)))
-     'project project
-     'jobset jobset)))
-
-(defun guix-hydra-jobset-info-insert-url (entry)
-  "Insert Hydra URL for the jobset ENTRY."
-  (guix-insert-button (guix-hydra-jobset-url
-                       (guix-entry-value entry 'project)
-                       (guix-entry-value entry 'name))
-                      'guix-url))
-
-\f
-;;; Hydra jobset 'list'
-
-(guix-hydra-list-define-interface hydra-jobset
-  :mode-name "Hydra-Jobset-List"
-  :buffer-name "*Guix Hydra Jobset List*"
-  :format '((name nil 25 t)
-            (project nil 10 t)
-            (scheduled nil 12 t)
-            (succeeded nil 12 t)
-            (failed nil 9 t)
-            (total nil 10 t)))
-
-(let ((map guix-hydra-jobset-list-mode-map))
-  (define-key map (kbd "B") 'guix-hydra-jobset-list-latest-builds))
-
-(defun guix-hydra-jobset-list-latest-builds (number &rest args)
-  "Display latest NUMBER of Hydra builds of the current jobset.
-Interactively, prompt for NUMBER.  With prefix argument, prompt
-for all ARGS."
-  (interactive
-   (let ((entry (guix-list-current-entry)))
-     (guix-hydra-build-latest-prompt-args
-      :project (guix-entry-value entry 'project)
-      :jobset  (guix-entry-value entry 'name))))
-  (apply #'guix-hydra-latest-builds number args))
-
-\f
-;;; Interactive commands
-
-;;;###autoload
-(defun guix-hydra-jobsets (project)
-  "Display jobsets of PROJECT."
-  (interactive (list (guix-hydra-read-project)))
-  (guix-hydra-jobset-get-display 'project project))
-
-(provide 'guix-hydra-jobset)
-
-;;; guix-hydra-jobset.el ends here
diff --git a/emacs/guix-hydra.el b/emacs/guix-hydra.el
deleted file mode 100644
index 9f876e7..0000000
--- a/emacs/guix-hydra.el
+++ /dev/null
@@ -1,367 +0,0 @@
-;;; guix-hydra.el --- Common code for interacting with Hydra  -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides some general code for 'list'/'info' interfaces for
-;; Hydra (Guix build farm).
-
-;;; Code:
-
-(require 'json)
-(require 'guix-buffer)
-(require 'guix-entry)
-(require 'guix-utils)
-(require 'guix-help-vars)
-
-(guix-define-groups hydra)
-
-(defvar guix-hydra-job-regexp
-  (concat ".*\\." (regexp-opt guix-help-system-types) "\\'")
-  "Regexp matching a full name of Hydra job (including system).")
-
-(defun guix-hydra-job-name-specification (name version)
-  "Return Hydra's job name specification by NAME and VERSION."
-  (concat name "-" version))
-
-(defun guix-hydra-message (entries search-type &rest _)
-  "Display a message after showing Hydra ENTRIES."
-  ;; XXX Add more messages maybe.
-  (when (null entries)
-    (if (eq search-type 'fake)
-        (message "The update is impossible due to lack of Hydra API.")
-      (message "Hydra has returned no results."))))
-
-(defun guix-hydra-list-describe (ids)
-  "Describe 'hydra' entries with IDS (list of identifiers)."
-  (guix-buffer-display-entries
-   (guix-entries-by-ids ids (guix-buffer-current-entries))
-   'info (guix-buffer-current-entry-type)
-   ;; Hydra does not provide an API to receive builds/jobsets by
-   ;; IDs/names, so we use a 'fake' search type.
-   '(fake)
-   'add))
-
-\f
-;;; Readers
-
-(defvar guix-hydra-projects
-  '("gnu" "guix")
-  "List of available Hydra projects.")
-
-(guix-define-readers
- :completions-var guix-hydra-projects
- :single-reader guix-hydra-read-project
- :single-prompt "Project: ")
-
-(guix-define-readers
- :single-reader guix-hydra-read-jobset
- :single-prompt "Jobset: ")
-
-(guix-define-readers
- :single-reader guix-hydra-read-job
- :single-prompt "Job: ")
-
-(guix-define-readers
- :completions-var guix-help-system-types
- :single-reader guix-hydra-read-system
- :single-prompt "System: ")
-
-\f
-;;; Defining URLs
-
-(defvar guix-hydra-url "http://hydra.gnu.org"
-  "URL of the Hydra build farm.")
-
-(defun guix-hydra-url (&rest url-parts)
-  "Return Hydra URL."
-  (apply #'concat guix-hydra-url "/" url-parts))
-
-(defun guix-hydra-api-url (type args)
-  "Return URL for receiving data using Hydra API.
-TYPE is the name of an allowed method.
-ARGS is alist of (KEY . VALUE) pairs.
-Skip ARG, if VALUE is nil or an empty string."
-  (declare (indent 1))
-  (let* ((fields (mapcar
-                  (lambda (arg)
-                    (pcase arg
-                      (`(,key . ,value)
-                       (unless (or (null value)
-                                   (equal "" value))
-                         (concat (guix-hexify key) "="
-                                 (guix-hexify value))))
-                      (_ (error "Wrong argument '%s'" arg))))
-                  args))
-         (fields (mapconcat #'identity (delq nil fields) "&")))
-    (guix-hydra-url "api/" type "?" fields)))
-
-\f
-;;; Receiving data from Hydra
-
-(defun guix-hydra-receive-data (url)
-  "Return output received from URL and processed with `json-read'."
-  (with-temp-buffer
-    (url-insert-file-contents url)
-    (goto-char (point-min))
-    (let ((json-key-type 'symbol)
-          (json-array-type 'list)
-          (json-object-type 'alist))
-      (json-read))))
-
-(defun guix-hydra-get-entries (entry-type search-type &rest args)
-  "Receive ENTRY-TYPE entries from Hydra.
-SEARCH-TYPE is one of the types defined by `guix-hydra-define-interface'."
-  (unless (eq search-type 'fake)
-    (let* ((url         (apply #'guix-hydra-search-url
-                               entry-type search-type args))
-           (raw-entries (guix-hydra-receive-data url))
-           (entries     (guix-hydra-filter-entries
-                         raw-entries
-                         (guix-hydra-filters entry-type))))
-      entries)))
-
-\f
-;;; Filters for processing raw entries
-
-(defun guix-hydra-filter-entries (entries filters)
-  "Filter ENTRIES using FILTERS.
-Call `guix-modify' on each entry from ENTRIES."
-  (mapcar (lambda (entry)
-            (guix-modify entry filters))
-          entries))
-
-(defun guix-hydra-filter-names (entry name-alist)
-  "Replace names of ENTRY parameters using NAME-ALIST.
-Each element of NAME-ALIST is (OLD-NAME . NEW-NAME) pair."
-  (mapcar (lambda (param)
-            (pcase param
-              (`(,name . ,val)
-               (let ((new-name (guix-assq-value name-alist name)))
-                 (if new-name
-                     (cons new-name val)
-                   param)))))
-          entry))
-
-(defun guix-hydra-filter-boolean (entry params)
-  "Convert number PARAMS (0/1) of ENTRY to boolean values (nil/t)."
-  (mapcar (lambda (param)
-            (pcase param
-              (`(,name . ,val)
-               (if (memq name params)
-                   (cons name (guix-number->bool val))
-                 param))))
-          entry))
-
-\f
-;;; Wrappers for defined variables
-
-(defvar guix-hydra-entry-type-data nil
-  "Alist with hydra entry type data.
-This alist is filled by `guix-hydra-define-entry-type' macro.")
-
-(defun guix-hydra-entry-type-value (entry-type symbol)
-  "Return SYMBOL's value for ENTRY-TYPE from `guix-hydra'."
-  (symbol-value (guix-assq-value guix-hydra-entry-type-data
-                                 entry-type symbol)))
-
-(defun guix-hydra-search-url (entry-type search-type &rest args)
-  "Return URL to receive ENTRY-TYPE entries from Hydra."
-  (apply (guix-assq-value (guix-hydra-entry-type-value
-                           entry-type 'search-types)
-                          search-type)
-         args))
-
-(defun guix-hydra-filters (entry-type)
-  "Return a list of filters for ENTRY-TYPE."
-  (guix-hydra-entry-type-value entry-type 'filters))
-
-\f
-;;; Interface definers
-
-(defmacro guix-hydra-define-entry-type (entry-type &rest args)
-  "Define general code for ENTRY-TYPE.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-Required keywords:
-
-  - `:search-types' - default value of the generated
-    `guix-ENTRY-TYPE-search-types' variable.
-
-Optional keywords:
-
-  - `:filters' - default value of the generated
-    `guix-ENTRY-TYPE-filters' variable.
-
-  - `:filter-names' - if specified, a generated
-    `guix-ENTRY-TYPE-filter-names' function for filtering these
-    names will be added to `guix-ENTRY-TYPE-filters' variable.
-
-  - `:filter-boolean-params' - if specified, a generated
-    `guix-ENTRY-TYPE-filter-boolean' function for filtering these
-    names will be added to `guix-ENTRY-TYPE-filters' variable.
-
-The rest keyword arguments are passed to
-`guix-define-entry-type' macro."
-  (declare (indent 1))
-  (let* ((entry-type-str     (symbol-name entry-type))
-         (prefix             (concat "guix-" entry-type-str))
-         (search-types-var   (intern (concat prefix "-search-types")))
-         (filters-var        (intern (concat prefix "-filters")))
-         (get-fun            (intern (concat prefix "-get-entries"))))
-    (guix-keyword-args-let args
-        ((search-types-val   :search-types)
-         (filters-val        :filters)
-         (filter-names-val   :filter-names)
-         (filter-bool-val    :filter-boolean-params))
-      `(progn
-         (defvar ,search-types-var ,search-types-val
-           ,(format "\
-Alist of search types and according URL functions.
-Functions are used to define URL to receive '%s' entries."
-                    entry-type-str))
-
-         (defvar ,filters-var ,filters-val
-           ,(format "\
-List of filters for '%s' parameters.
-Each filter is a function that should take an entry as a single
-argument, and should also return an entry."
-                    entry-type-str))
-
-         ,(when filter-bool-val
-            (let ((filter-bool-var (intern (concat prefix
-                                                   "-filter-boolean-params")))
-                  (filter-bool-fun (intern (concat prefix
-                                                   "-filter-boolean"))))
-              `(progn
-                 (defvar ,filter-bool-var ,filter-bool-val
-                   ,(format "\
-List of '%s' parameters that should be transformed to boolean values."
-                            entry-type-str))
-
-                 (defun ,filter-bool-fun (entry)
-                   ,(format "\
-Run `guix-hydra-filter-boolean' with `%S' variable."
-                            filter-bool-var)
-                   (guix-hydra-filter-boolean entry ,filter-bool-var))
-
-                 (setq ,filters-var
-                       (cons ',filter-bool-fun ,filters-var)))))
-
-         ;; Do not move this clause up!: name filtering should be
-         ;; performed before any other filtering, so this filter should
-         ;; be consed after the boolean filter.
-         ,(when filter-names-val
-            (let* ((filter-names-var (intern (concat prefix
-                                                     "-filter-names")))
-                   (filter-names-fun filter-names-var))
-              `(progn
-                 (defvar ,filter-names-var ,filter-names-val
-                   ,(format "\
-Alist of '%s' parameter names returned by Hydra API and names
-used internally by the elisp code of this package."
-                            entry-type-str))
-
-                 (defun ,filter-names-fun (entry)
-                   ,(format "\
-Run `guix-hydra-filter-names' with `%S' variable."
-                            filter-names-var)
-                   (guix-hydra-filter-names entry ,filter-names-var))
-
-                 (setq ,filters-var
-                       (cons ',filter-names-fun ,filters-var)))))
-
-         (defun ,get-fun (search-type &rest args)
-           ,(format "\
-Receive '%s' entries.
-See `guix-hydra-get-entries' for details."
-                    entry-type-str)
-           (apply #'guix-hydra-get-entries
-                  ',entry-type search-type args))
-
-         (guix-alist-put!
-          '((search-types . ,search-types-var)
-            (filters      . ,filters-var))
-          'guix-hydra-entry-type-data ',entry-type)
-
-         (guix-define-entry-type ,entry-type
-           :parent-group guix-hydra
-           :parent-faces-group guix-hydra-faces
-           ,@%foreign-args)))))
-
-(defmacro guix-hydra-define-interface (buffer-type entry-type &rest args)
-  "Define BUFFER-TYPE interface for displaying ENTRY-TYPE entries.
-
-This macro should be called after calling
-`guix-hydra-define-entry-type' with the same ENTRY-TYPE.
-
-ARGS are passed to `guix-BUFFER-TYPE-define-interface' macro."
-  (declare (indent 2))
-  (let* ((entry-type-str  (symbol-name entry-type))
-         (buffer-type-str (symbol-name buffer-type))
-         (get-fun         (intern (concat "guix-" entry-type-str
-                                          "-get-entries")))
-         (definer         (intern (concat "guix-" buffer-type-str
-                                          "-define-interface"))))
-    `(,definer ,entry-type
-       :get-entries-function ',get-fun
-       :message-function 'guix-hydra-message
-       ,@args)))
-
-(defmacro guix-hydra-info-define-interface (entry-type &rest args)
-  "Define 'info' interface for displaying ENTRY-TYPE entries.
-See `guix-hydra-define-interface'."
-  (declare (indent 1))
-  `(guix-hydra-define-interface info ,entry-type
-     ,@args))
-
-(defmacro guix-hydra-list-define-interface (entry-type &rest args)
-  "Define 'list' interface for displaying ENTRY-TYPE entries.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-Optional keywords:
-
-  - `:describe-function' - default value of the generated
-    `guix-ENTRY-TYPE-list-describe-function' variable (if not
-    specified, use `guix-hydra-list-describe').
-
-The rest keyword arguments are passed to
-`guix-hydra-define-interface' macro."
-  (declare (indent 1))
-  (guix-keyword-args-let args
-      ((describe-val :describe-function))
-    `(guix-hydra-define-interface list ,entry-type
-       :describe-function ,(or describe-val ''guix-hydra-list-describe)
-       ,@args)))
-
-\f
-(defvar guix-hydra-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group (or "guix-hydra-define-entry-type"
-                           "guix-hydra-define-interface"
-                           "guix-hydra-info-define-interface"
-                           "guix-hydra-list-define-interface"))
-            symbol-end)
-       . 1))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-hydra-font-lock-keywords)
-
-(provide 'guix-hydra)
-
-;;; guix-hydra.el ends here
diff --git a/emacs/guix-info.el b/emacs/guix-info.el
deleted file mode 100644
index 6aefd2f..0000000
--- a/emacs/guix-info.el
+++ /dev/null
@@ -1,482 +0,0 @@
-;;; guix-info.el --- 'Info' buffer interface for displaying data  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
-;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides 'info' (help-like) buffer interface for displaying
-;; an arbitrary data.
-
-;;; Code:
-
-(require 'guix-buffer)
-(require 'guix-entry)
-(require 'guix-utils)
-
-(guix-define-buffer-type info)
-
-(defface guix-info-heading
-  '((((type tty pc) (class color)) :weight bold)
-    (t :height 1.6 :weight bold :inherit variable-pitch))
-  "Face for headings."
-  :group 'guix-info-faces)
-
-(defface guix-info-param-title
-  '((t :inherit font-lock-type-face))
-  "Face used for titles of parameters."
-  :group 'guix-info-faces)
-
-(defface guix-info-file-name
-  '((t :inherit link))
-  "Face used for file names."
-  :group 'guix-info-faces)
-
-(defface guix-info-url
-  '((t :inherit link))
-  "Face used for URLs."
-  :group 'guix-info-faces)
-
-(defface guix-info-time
-  '((t :inherit font-lock-constant-face))
-  "Face used for timestamps."
-  :group 'guix-info-faces)
-
-(defface guix-info-action-button
-  '((((type x w32 ns) (class color))
-     :box (:line-width 2 :style released-button)
-     :background "lightgrey" :foreground "black")
-    (t :inherit button))
-  "Face used for action buttons."
-  :group 'guix-info-faces)
-
-(defface guix-info-action-button-mouse
-  '((((type x w32 ns) (class color))
-     :box (:line-width 2 :style released-button)
-     :background "grey90" :foreground "black")
-    (t :inherit highlight))
-  "Mouse face used for action buttons."
-  :group 'guix-info-faces)
-
-(defcustom guix-info-ignore-empty-values nil
-  "If non-nil, do not display parameters with nil values."
-  :type 'boolean
-  :group 'guix-info)
-
-(defcustom guix-info-fill t
-  "If non-nil, fill string parameters to fit the window.
-If nil, insert text parameters (like synopsis or description) in
-a raw form."
-  :type 'boolean
-  :group 'guix-info)
-
-(defvar guix-info-param-title-format "%-18s: "
-  "String used to format a title of a parameter.
-It should be a '%s'-sequence.  After inserting a title formatted
-with this string, a value of the parameter is inserted.
-This string is used by `guix-info-insert-title-format'.")
-
-(defvar guix-info-multiline-prefix
-  (make-string (length (format guix-info-param-title-format " "))
-               ?\s)
-  "String used to format multi-line parameter values.
-If a value occupies more than one line, this string is inserted
-in the beginning of each line after the first one.
-This string is used by `guix-info-insert-value-format'.")
-
-(defvar guix-info-indent 2
-  "Number of spaces used to indent various parts of inserted text.")
-
-(defvar guix-info-delimiter "\n\f\n"
-  "String used to separate entries.")
-
-\f
-;;; Wrappers for 'info' variables
-
-(defvar guix-info-data nil
-  "Alist with 'info' data.
-This alist is filled by `guix-info-define-interface' macro.")
-
-(defun guix-info-value (entry-type symbol)
-  "Return SYMBOL's value for ENTRY-TYPE from `guix-info-data'."
-  (symbol-value (guix-assq-value guix-info-data entry-type symbol)))
-
-(defun guix-info-param-title (entry-type param)
-  "Return a title of an ENTRY-TYPE parameter PARAM."
-  (guix-buffer-param-title 'info entry-type param))
-
-(defun guix-info-format (entry-type)
-  "Return 'info' format for ENTRY-TYPE."
-  (guix-info-value entry-type 'format))
-
-(defun guix-info-displayed-params (entry-type)
-  "Return a list of ENTRY-TYPE parameters that should be displayed."
-  (delq nil
-        (mapcar (lambda (spec)
-                  (pcase spec
-                    (`(,param . ,_) param)))
-                (guix-info-format entry-type))))
-
-\f
-;;; Inserting entries
-
-(defvar guix-info-title-aliases
-  '((format . guix-info-insert-title-format)
-    (simple . guix-info-insert-title-simple))
-  "Alist of aliases and functions to insert titles.")
-
-(defvar guix-info-value-aliases
-  '((format . guix-info-insert-value-format)
-    (indent . guix-info-insert-value-indent)
-    (simple . guix-info-insert-value-simple)
-    (time   . guix-info-insert-time))
-  "Alist of aliases and functions to insert values.")
-
-(defun guix-info-title-function (fun-or-alias)
-  "Convert FUN-OR-ALIAS into a function to insert a title."
-  (or (guix-assq-value guix-info-title-aliases fun-or-alias)
-      fun-or-alias))
-
-(defun guix-info-value-function (fun-or-alias)
-  "Convert FUN-OR-ALIAS into a function to insert a value."
-  (or (guix-assq-value guix-info-value-aliases fun-or-alias)
-      fun-or-alias))
-
-(defun guix-info-title-method->function (method)
-  "Convert title METHOD into a function to insert a title."
-  (pcase method
-    ((pred null) #'ignore)
-    ((pred symbolp) (guix-info-title-function method))
-    (`(,fun-or-alias . ,rest-args)
-     (lambda (title)
-       (apply (guix-info-title-function fun-or-alias)
-              title rest-args)))
-    (_ (error "Unknown title method '%S'" method))))
-
-(defun guix-info-value-method->function (method)
-  "Convert value METHOD into a function to insert a value."
-  (pcase method
-    ((pred null) #'ignore)
-    ((pred functionp) method)
-    (`(,fun-or-alias . ,rest-args)
-     (lambda (value _)
-       (apply (guix-info-value-function fun-or-alias)
-              value rest-args)))
-    (_ (error "Unknown value method '%S'" method))))
-
-(defun guix-info-fill-column ()
-  "Return fill column for the current window."
-  (min (window-width) fill-column))
-
-(defun guix-info-get-indent (&optional level)
-  "Return `guix-info-indent' \"multiplied\" by LEVEL spaces.
-LEVEL is 1 by default."
-  (make-string (* guix-info-indent (or level 1)) ?\s))
-
-(defun guix-info-insert-indent (&optional level)
-  "Insert `guix-info-indent' spaces LEVEL times (1 by default)."
-  (insert (guix-info-get-indent level)))
-
-(defun guix-info-insert-entries (entries entry-type)
-  "Display ENTRY-TYPE ENTRIES in the current info buffer."
-  (guix-mapinsert (lambda (entry)
-                    (guix-info-insert-entry entry entry-type))
-                  entries
-                  guix-info-delimiter))
-
-(defun guix-info-insert-entry (entry entry-type &optional indent-level)
-  "Insert ENTRY of ENTRY-TYPE into the current info buffer.
-If INDENT-LEVEL is non-nil, indent displayed data by this number
-of `guix-info-indent' spaces."
-  (guix-with-indent (* (or indent-level 0)
-                       guix-info-indent)
-    (dolist (spec (guix-info-format entry-type))
-      (guix-info-insert-entry-unit spec entry entry-type))))
-
-(defun guix-info-insert-entry-unit (format-spec entry entry-type)
-  "Insert title and value of a PARAM at point.
-ENTRY is alist with parameters and their values.
-ENTRY-TYPE is a type of ENTRY."
-  (pcase format-spec
-    ((pred functionp)
-     (funcall format-spec entry)
-     (insert "\n"))
-    (`(,param ,title-method ,value-method)
-     (let ((value (guix-entry-value entry param)))
-       (unless (and guix-info-ignore-empty-values (null value))
-         (let ((title        (guix-info-param-title entry-type param))
-               (insert-title (guix-info-title-method->function title-method))
-               (insert-value (guix-info-value-method->function value-method)))
-           (funcall insert-title title)
-           (funcall insert-value value entry)
-           (insert "\n")))))
-    (_ (error "Unknown format specification '%S'" format-spec))))
-
-(defun guix-info-insert-title-simple (title &optional face)
-  "Insert \"TITLE: \" string at point.
-If FACE is nil, use `guix-info-param-title'."
-  (guix-format-insert title
-                      (or face 'guix-info-param-title)
-                      "%s: "))
-
-(defun guix-info-insert-title-format (title &optional face)
-  "Insert TITLE using `guix-info-param-title-format' at point.
-If FACE is nil, use `guix-info-param-title'."
-  (guix-format-insert title
-                      (or face 'guix-info-param-title)
-                      guix-info-param-title-format))
-
-(defun guix-info-insert-value-simple (value &optional button-or-face indent)
-  "Format and insert parameter VALUE at point.
-
-VALUE may be split into several short lines to fit the current
-window, depending on `guix-info-fill', and each line is indented
-with INDENT number of spaces.
-
-If BUTTON-OR-FACE is a button type symbol, transform VALUE into
-this (these) button(s) and insert each one on a new line.  If it
-is a face symbol, propertize inserted line(s) with this face."
-  (or indent (setq indent 0))
-  (guix-with-indent indent
-    (let* ((button?  (guix-button-type? button-or-face))
-           (face     (unless button? button-or-face))
-           (fill-col (unless (or button?
-                                 (and (stringp value)
-                                      (not guix-info-fill)))
-                       (- (guix-info-fill-column) indent)))
-           (value    (if (and value button?)
-                         (guix-buttonize value button-or-face "\n")
-                       value)))
-      (guix-split-insert value face fill-col "\n"))))
-
-(defun guix-info-insert-value-indent (value &optional button-or-face)
-  "Format and insert parameter VALUE at point.
-
-This function is intended to be called after inserting a title
-with `guix-info-insert-title-simple'.
-
-VALUE may be split into several short lines to fit the current
-window, depending on `guix-info-fill', and each line is indented
-with `guix-info-indent'.
-
-For the meaning of BUTTON-OR-FACE, see `guix-info-insert-value-simple'."
-  (when value (insert "\n"))
-  (guix-info-insert-value-simple value button-or-face guix-info-indent))
-
-(defun guix-info-insert-value-format (value &optional button-or-face
-                                            &rest button-properties)
-  "Format and insert parameter VALUE at point.
-
-This function is intended to be called after inserting a title
-with `guix-info-insert-title-format'.
-
-VALUE may be split into several short lines to fit the current
-window, depending on `guix-info-fill' and
-`guix-info-multiline-prefix'.  If VALUE is a list, its elements
-will be separated with `guix-list-separator'.
-
-If BUTTON-OR-FACE is a button type symbol, transform VALUE into
-this (these) button(s).  If it is a face symbol, propertize
-inserted line(s) with this face.
-
-BUTTON-PROPERTIES are passed to `guix-buttonize' (only if
-BUTTON-OR-FACE is a button type)."
-  (let* ((button?  (guix-button-type? button-or-face))
-         (face     (unless button? button-or-face))
-         (fill-col (when (or button?
-                             guix-info-fill
-                             (not (stringp value)))
-                     (- (guix-info-fill-column)
-                        (length guix-info-multiline-prefix))))
-         (value    (if (and value button?)
-                       (apply #'guix-buttonize
-                              value button-or-face guix-list-separator
-                              button-properties)
-                     value)))
-    (guix-split-insert value face fill-col
-                       (concat "\n" guix-info-multiline-prefix))))
-
-(defun guix-info-insert-time (seconds &optional face)
-  "Insert formatted time string using SECONDS at point."
-  (guix-format-insert (guix-get-time-string seconds)
-                      (or face 'guix-info-time)))
-
-\f
-;;; Buttons
-
-(defvar guix-info-button-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map button-map)
-    (define-key map (kbd "c") 'guix-info-button-copy-label)
-    map)
-  "Keymap for buttons in info buffers.")
-
-(define-button-type 'guix
-  'keymap guix-info-button-map
-  'follow-link t)
-
-(define-button-type 'guix-action
-  :supertype 'guix
-  'face 'guix-info-action-button
-  'mouse-face 'guix-info-action-button-mouse)
-
-(define-button-type 'guix-file
-  :supertype 'guix
-  'face 'guix-info-file-name
-  'help-echo "Find file"
-  'action (lambda (btn)
-            (guix-find-file (button-label btn))))
-
-(define-button-type 'guix-url
-  :supertype 'guix
-  'face 'guix-info-url
-  'help-echo "Browse URL"
-  'action (lambda (btn)
-            (browse-url (button-label btn))))
-
-(defun guix-info-button-copy-label (&optional pos)
-  "Copy a label of the button at POS into kill ring.
-If POS is nil, use the current point position."
-  (interactive)
-  (let ((button (button-at (or pos (point)))))
-    (when button
-      (guix-copy-as-kill (button-label button)))))
-
-(defun guix-info-insert-action-button (label action &optional message
-                                             &rest properties)
-  "Make action button with LABEL and insert it at point.
-ACTION is a function called when the button is pressed.  It
-should accept button as the argument.
-MESSAGE is a button message.
-See `insert-text-button' for the meaning of PROPERTIES."
-  (apply #'guix-insert-button
-         label 'guix-action
-         'action action
-         'help-echo message
-         properties))
-
-\f
-;;; Major mode and interface definer
-
-(defvar guix-info-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent
-     map (make-composed-keymap (list guix-buffer-map button-buffer-map)
-                               special-mode-map))
-    map)
-  "Keymap for `guix-info-mode' buffers.")
-
-(define-derived-mode guix-info-mode special-mode "Guix-Info"
-  "Parent mode for displaying data in 'info' form."
-  (setq-local revert-buffer-function 'guix-buffer-revert))
-
-(defun guix-info-mode-initialize ()
-  "Set up the current 'info' buffer."
-  ;; Without this, syntactic fontification is performed, and it may
-  ;; break our highlighting.  For example, description of "emacs-typo"
-  ;; package contains a single " (double-quote) character, so the
-  ;; default syntactic fontification highlights the rest text after it
-  ;; as a string.  See (info "(elisp) Font Lock Basics") for details.
-  (setq font-lock-defaults '(nil t)))
-
-(defmacro guix-info-define-interface (entry-type &rest args)
-  "Define 'info' interface for displaying ENTRY-TYPE entries.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-Required keywords:
-
-  - `:format' - default value of the generated
-    `guix-ENTRY-TYPE-info-format' variable.
-
-The rest keyword arguments are passed to
-`guix-buffer-define-interface' macro."
-  (declare (indent 1))
-  (let* ((entry-type-str     (symbol-name entry-type))
-         (prefix             (concat "guix-" entry-type-str "-info"))
-         (group              (intern prefix))
-         (format-var         (intern (concat prefix "-format"))))
-    (guix-keyword-args-let args
-        ((show-entries-val   :show-entries-function)
-         (format-val         :format))
-      `(progn
-         (defcustom ,format-var ,format-val
-           ,(format "\
-List of methods for inserting '%s' entry.
-Each METHOD should be either a function or should have the
-following form:
-
-  (PARAM INSERT-TITLE INSERT-VALUE)
-
-If METHOD is a function, it is called with an entry as argument.
-
-PARAM is a name of '%s' entry parameter.
-
-INSERT-TITLE may be either a symbol or a list.  If it is a
-symbol, it should be a function or an alias from
-`guix-info-title-aliases', in which case it is called with title
-as argument.  If it is a list, it should have a
-form (FUN-OR-ALIAS [ARGS ...]), in which case FUN-OR-ALIAS is
-called with title and ARGS as arguments.
-
-INSERT-VALUE may be either a symbol or a list.  If it is a
-symbol, it should be a function or an alias from
-`guix-info-value-aliases', in which case it is called with value
-and entry as arguments.  If it is a list, it should have a
-form (FUN-OR-ALIAS [ARGS ...]), in which case FUN-OR-ALIAS is
-called with value and ARGS as arguments.
-
-Parameters are inserted in the same order as defined by this list.
-After calling each METHOD, a new line is inserted."
-                    entry-type-str entry-type-str)
-           :type 'sexp
-           :group ',group)
-
-         (guix-alist-put!
-          '((format . ,format-var))
-          'guix-info-data ',entry-type)
-
-         ,(if show-entries-val
-              `(guix-buffer-define-interface info ,entry-type
-                 :show-entries-function ,show-entries-val
-                 ,@%foreign-args)
-
-            (let ((insert-fun (intern (concat prefix "-insert-entries"))))
-              `(progn
-                 (defun ,insert-fun (entries)
-                   ,(format "\
-Print '%s' ENTRIES in the current 'info' buffer."
-                            entry-type-str)
-                   (guix-info-insert-entries entries ',entry-type))
-
-                 (guix-buffer-define-interface info ,entry-type
-                   :insert-entries-function ',insert-fun
-                   :mode-init-function 'guix-info-mode-initialize
-                   ,@%foreign-args))))))))
-
-\f
-(defvar guix-info-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group "guix-info-define-interface")
-            symbol-end)
-       . 1))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-info-font-lock-keywords)
-
-(provide 'guix-info)
-
-;;; guix-info.el ends here
diff --git a/emacs/guix-init.el b/emacs/guix-init.el
deleted file mode 100644
index bd75e54..0000000
--- a/emacs/guix-init.el
+++ /dev/null
@@ -1,3 +0,0 @@
-(require 'guix-autoloads)
-(message "(require 'guix-init) is obsolete, use (require 'guix-autoloads) instead.")
-(provide 'guix-init)
diff --git a/emacs/guix-license.el b/emacs/guix-license.el
deleted file mode 100644
index 6003a21..0000000
--- a/emacs/guix-license.el
+++ /dev/null
@@ -1,65 +0,0 @@
-;;; guix-license.el --- Licenses
-
-;; Copyright © 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides the code to work with licenses of Guix packages.
-
-;;; Code:
-
-(require 'guix-read)
-(require 'guix-backend)
-(require 'guix-guile)
-
-(defun guix-license-file (&optional directory)
-  "Return name of the file with license definitions.
-DIRECTORY is a directory with Guix source (`guix-directory' by default)."
-  (expand-file-name "guix/licenses.scm"
-                    (or directory guix-directory)))
-
-(defun guix-lookup-license-url (license)
-  "Return URL of a LICENSE."
-  (or (guix-eval-read (guix-make-guile-expression
-                       'lookup-license-uri license))
-      (error "Hm, I don't know URL of '%s' license" license)))
-
-;;;###autoload
-(defun guix-find-license-definition (license &optional directory)
-  "Open licenses file from DIRECTORY and move to the LICENSE definition.
-See `guix-license-file' for the meaning of DIRECTORY.
-Interactively, with prefix argument, prompt for DIRECTORY."
-  (interactive
-   (list (guix-read-license-name)
-         (guix-read-directory)))
-  (find-file (guix-license-file directory))
-  (goto-char (point-min))
-  (when (re-search-forward (concat "\"" (regexp-quote license) "\"")
-                           nil t)
-    (beginning-of-defun)
-    (recenter 1)))
-
-;;;###autoload
-(defun guix-browse-license-url (license)
-  "Browse URL of a LICENSE."
-  (interactive (list (guix-read-license-name)))
-  (browse-url (guix-lookup-license-url license)))
-
-(provide 'guix-license)
-
-;;; guix-license.el ends here
diff --git a/emacs/guix-list.el b/emacs/guix-list.el
deleted file mode 100644
index c91c67c..0000000
--- a/emacs/guix-list.el
+++ /dev/null
@@ -1,585 +0,0 @@
-;;; guix-list.el --- 'List' buffer interface for displaying data  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides 'list' buffer interface for displaying an arbitrary
-;; data.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'tabulated-list)
-(require 'guix-buffer)
-(require 'guix-info)
-(require 'guix-entry)
-(require 'guix-utils)
-
-(guix-define-buffer-type list)
-
-(defface guix-list-file-name
-  '((t :inherit guix-info-file-name))
-  "Face used for file names."
-  :group 'guix-list-faces)
-
-(defface guix-list-url
-  '((t :inherit guix-info-url))
-  "Face used for URLs."
-  :group 'guix-list-faces)
-
-(defface guix-list-time
-  '((t :inherit guix-info-time))
-  "Face used for time stamps."
-  :group 'guix-list-faces)
-
-(defun guix-list-describe (&optional mark-names)
-  "Describe entries marked with a general mark.
-'Describe' means display entries in 'info' buffer.
-If no entries are marked, describe the current entry.
-With prefix argument, describe entries marked with any mark."
-  (interactive (list (unless current-prefix-arg '(general))))
-  (let* ((ids        (or (apply #'guix-list-get-marked-id-list mark-names)
-                         (list (guix-list-current-id))))
-         (count      (length ids))
-         (entry-type (guix-buffer-current-entry-type)))
-    (when (or (<= count (guix-list-describe-warning-count entry-type))
-              (y-or-n-p (format "Do you really want to describe %d entries? "
-                                count)))
-      (guix-list-describe-entries entry-type ids))))
-
-\f
-;;; Wrappers for 'list' variables
-
-(defvar guix-list-data nil
-  "Alist with 'list' data.
-This alist is filled by `guix-list-define-interface' macro.")
-
-(defun guix-list-value (entry-type symbol)
-  "Return SYMBOL's value for ENTRY-TYPE from `guix-list-data'."
-  (symbol-value (guix-assq-value guix-list-data entry-type symbol)))
-
-(defun guix-list-param-title (entry-type param)
-  "Return column title of an ENTRY-TYPE parameter PARAM."
-  (guix-buffer-param-title 'list entry-type param))
-
-(defun guix-list-format (entry-type)
-  "Return column format for ENTRY-TYPE."
-  (guix-list-value entry-type 'format))
-
-(defun guix-list-displayed-params (entry-type)
-  "Return a list of ENTRY-TYPE parameters that should be displayed."
-  (mapcar #'car (guix-list-format entry-type)))
-
-(defun guix-list-sort-key (entry-type)
-  "Return sort key for ENTRY-TYPE."
-  (guix-list-value entry-type 'sort-key))
-
-(defun guix-list-additional-marks (entry-type)
-  "Return alist of additional marks for ENTRY-TYPE."
-  (guix-list-value entry-type 'marks))
-
-(defun guix-list-single-entry? (entry-type)
-  "Return non-nil, if a single entry of ENTRY-TYPE should be listed."
-  (guix-list-value entry-type 'list-single))
-
-(defun guix-list-describe-warning-count (entry-type)
-  "Return the maximum number of ENTRY-TYPE entries to describe."
-  (guix-list-value entry-type 'describe-count))
-
-(defun guix-list-describe-entries (entry-type ids)
-  "Describe ENTRY-TYPE entries with IDS in 'info' buffer"
-  (funcall (guix-list-value entry-type 'describe)
-           ids))
-
-\f
-;;; Tabulated list internals
-
-(defun guix-list-sort-numerically (column a b)
-  "Compare COLUMN of tabulated entries A and B numerically.
-This function is used for sort predicates for `tabulated-list-format'.
-Return non-nil, if B is bigger than A."
-  (cl-flet ((num (entry)
-              (string-to-number (aref (cadr entry) column))))
-    (> (num b) (num a))))
-
-(defmacro guix-list-define-numerical-sorter (column)
-  "Define numerical sort predicate for COLUMN.
-See `guix-list-sort-numerically' for details."
-  (let ((name (intern (format "guix-list-sort-numerically-%d" column)))
-        (doc  (format "\
-Predicate to sort tabulated list by column %d numerically.
-See `guix-list-sort-numerically' for details."
-                      column)))
-    `(defun ,name (a b)
-       ,doc
-       (guix-list-sort-numerically ,column a b))))
-
-(defmacro guix-list-define-numerical-sorters (n)
-  "Define numerical sort predicates for columns from 0 to N.
-See `guix-list-define-numerical-sorter' for details."
-  `(progn
-     ,@(mapcar (lambda (i)
-                 `(guix-list-define-numerical-sorter ,i))
-               (number-sequence 0 n))))
-
-(guix-list-define-numerical-sorters 9)
-
-(defun guix-list-tabulated-sort-key (entry-type)
-  "Return ENTRY-TYPE sort key for `tabulated-list-sort-key'."
-  (let ((sort-key (guix-list-sort-key entry-type)))
-    (and sort-key
-         (cons (guix-list-param-title entry-type (car sort-key))
-               (cdr sort-key)))))
-
-(defun guix-list-tabulated-vector (entry-type fun)
-  "Call FUN on each column specification for ENTRY-TYPE.
-
-FUN is applied to column specification as arguments (see
-`guix-list-format').
-
-Return a vector made of values of FUN calls."
-  (apply #'vector
-         (mapcar (lambda (col-spec)
-                   (apply fun col-spec))
-                 (guix-list-format entry-type))))
-
-(defun guix-list-tabulated-format (entry-type)
-  "Return ENTRY-TYPE list specification for `tabulated-list-format'."
-  (guix-list-tabulated-vector
-   entry-type
-   (lambda (param _ &rest rest-spec)
-     (cons (guix-list-param-title entry-type param)
-           rest-spec))))
-
-(defun guix-list-tabulated-entries (entries entry-type)
-  "Return a list of ENTRY-TYPE values for `tabulated-list-entries'."
-  (mapcar (lambda (entry)
-            (list (guix-entry-id entry)
-                  (guix-list-tabulated-entry entry entry-type)))
-          entries))
-
-(defun guix-list-tabulated-entry (entry entry-type)
-  "Return array of values for `tabulated-list-entries'.
-Parameters are taken from ENTRY-TYPE ENTRY."
-  (guix-list-tabulated-vector
-   entry-type
-   (lambda (param fun &rest _)
-     (let ((val (guix-entry-value entry param)))
-       (if fun
-           (funcall fun val entry)
-         (guix-get-string val))))))
-
-\f
-;;; Displaying entries
-
-(defun guix-list-get-display-entries (entry-type &rest args)
-  "Search for entries and show them in a 'list' buffer preferably."
-  (let ((entries (guix-buffer-get-entries 'list entry-type args)))
-    (if (or (null entries)      ; = 0
-            (cdr entries)       ; > 1
-            (guix-list-single-entry? entry-type)
-            (null (guix-buffer-value 'info entry-type 'show-entries)))
-        (guix-buffer-display-entries entries 'list entry-type args 'add)
-      (if (equal (guix-buffer-value 'info entry-type 'get-entries)
-                 (guix-buffer-value 'list entry-type 'get-entries))
-          (guix-buffer-display-entries entries 'info entry-type args 'add)
-        (guix-buffer-get-display-entries 'info entry-type args 'add)))))
-
-(defun guix-list-insert-entries (entries entry-type)
-  "Print ENTRY-TYPE ENTRIES in the current buffer."
-  (setq tabulated-list-entries
-        (guix-list-tabulated-entries entries entry-type))
-  (tabulated-list-print))
-
-(defun guix-list-get-one-line (val &optional _)
-  "Return one-line string from a multi-line string VAL.
-VAL may be nil."
-  (if val
-      (guix-get-one-line val)
-    (guix-get-string nil)))
-
-(defun guix-list-get-time (seconds &optional _)
-  "Return formatted time string from SECONDS."
-  (guix-get-string (guix-get-time-string seconds)
-                   'guix-list-time))
-
-(defun guix-list-get-file-name (file-name &optional _)
-  "Return FILE-NAME button specification for `tabulated-list-entries'."
-  (list file-name
-        'face 'guix-list-file-name
-        'action (lambda (btn) (find-file (button-label btn)))
-        'follow-link t
-        'help-echo "Find file"))
-
-(defun guix-list-get-url (url &optional _)
-  "Return URL button specification for `tabulated-list-entries'."
-  (list url
-        'face 'guix-list-url
-        'action (lambda (btn) (browse-url (button-label btn)))
-        'follow-link t
-        'help-echo "Browse URL"))
-
-\f
-;;; 'List' lines
-
-(defun guix-list-current-id ()
-  "Return ID of the entry at point."
-  (or (tabulated-list-get-id)
-      (user-error "No entry here")))
-
-(defun guix-list-current-entry ()
-  "Return entry at point."
-  (guix-entry-by-id (guix-list-current-id)
-                    (guix-buffer-current-entries)))
-
-(defun guix-list-for-each-line (fun &rest args)
-  "Call FUN with ARGS for each entry line."
-  (or (derived-mode-p 'guix-list-mode)
-      (error "The current buffer is not in Guix List mode"))
-  (save-excursion
-    (goto-char (point-min))
-    (while (not (eobp))
-      (apply fun args)
-      (forward-line))))
-
-(defun guix-list-fold-lines (fun init)
-  "Fold over entry lines in the current list buffer.
-Call FUN with RESULT as argument for each line, using INIT as
-the initial value of RESULT.  Return the final result."
-  (let ((res init))
-    (guix-list-for-each-line
-     (lambda () (setq res (funcall fun res))))
-    res))
-
-\f
-;;; Marking and sorting
-
-(defvar-local guix-list-marked nil
-  "List of the marked entries.
-Each element of the list has a form:
-
-  (ID MARK-NAME . ARGS)
-
-ID is an entry ID.
-MARK-NAME is a symbol from `guix-list-marks'.
-ARGS is a list of additional values.")
-
-(defvar-local guix-list-marks nil
-  "Alist of available mark names and mark characters.")
-
-(defvar guix-list-default-marks
-  '((empty   . ?\s)
-    (general . ?*))
-  "Alist of default mark names and mark characters.")
-
-(defun guix-list-marks (entry-type)
-  "Return alist of available marks for ENTRY-TYPE."
-  (append guix-list-default-marks
-          (guix-list-additional-marks entry-type)))
-
-(defun guix-list-get-mark (name)
-  "Return mark character by its NAME."
-  (or (guix-assq-value guix-list-marks name)
-      (error "Mark '%S' not found" name)))
-
-(defun guix-list-get-mark-string (name)
-  "Return mark string by its NAME."
-  (string (guix-list-get-mark name)))
-
-(defun guix-list-current-mark ()
-  "Return mark character of the current line."
-  (char-after (line-beginning-position)))
-
-(defun guix-list-get-marked (&rest mark-names)
-  "Return list of specs of entries marked with any mark from MARK-NAMES.
-Entry specs are elements from `guix-list-marked' list.
-If MARK-NAMES are not specified, use all marks from
-`guix-list-marks' except the `empty' one."
-  (or mark-names
-      (setq mark-names
-            (delq 'empty
-                  (mapcar #'car guix-list-marks))))
-  (cl-remove-if-not (lambda (assoc)
-                      (memq (cadr assoc) mark-names))
-                    guix-list-marked))
-
-(defun guix-list-get-marked-args (mark-name)
-  "Return list of (ID . ARGS) elements from lines marked with MARK-NAME.
-See `guix-list-marked' for the meaning of ARGS."
-  (mapcar (lambda (spec)
-            (let ((id (car spec))
-                  (args (cddr spec)))
-              (cons id args)))
-          (guix-list-get-marked mark-name)))
-
-(defun guix-list-get-marked-id-list (&rest mark-names)
-  "Return list of IDs of entries marked with any mark from MARK-NAMES.
-See `guix-list-get-marked' for details."
-  (mapcar #'car (apply #'guix-list-get-marked mark-names)))
-
-(defun guix-list--mark (mark-name &optional advance &rest args)
-  "Put a mark on the current line.
-Also add the current entry to `guix-list-marked' using its ID and ARGS.
-MARK-NAME is a symbol from `guix-list-marks'.
-If ADVANCE is non-nil, move forward by one line after marking."
-  (let ((id (guix-list-current-id)))
-    (if (eq mark-name 'empty)
-        (setq guix-list-marked (assq-delete-all id guix-list-marked))
-      (let ((assoc (assq id guix-list-marked))
-            (val (cons mark-name args)))
-        (if assoc
-            (setcdr assoc val)
-          (push (cons id val) guix-list-marked)))))
-  (tabulated-list-put-tag (guix-list-get-mark-string mark-name)
-                          advance))
-
-(defun guix-list-mark (&optional arg)
-  "Mark the current line and move to the next line.
-With ARG, mark all lines."
-  (interactive "P")
-  (if arg
-      (guix-list-mark-all)
-    (guix-list--mark 'general t)))
-
-(defun guix-list-mark-all (&optional mark-name)
-  "Mark all lines with MARK-NAME mark.
-MARK-NAME is a symbol from `guix-list-marks'.
-Interactively, put a general mark on all lines."
-  (interactive)
-  (or mark-name (setq mark-name 'general))
-  (guix-list-for-each-line #'guix-list--mark mark-name))
-
-(defun guix-list-unmark (&optional arg)
-  "Unmark the current line and move to the next line.
-With ARG, unmark all lines."
-  (interactive "P")
-  (if arg
-      (guix-list-unmark-all)
-    (guix-list--mark 'empty t)))
-
-(defun guix-list-unmark-backward ()
-  "Move up one line and unmark it."
-  (interactive)
-  (forward-line -1)
-  (guix-list--mark 'empty))
-
-(defun guix-list-unmark-all ()
-  "Unmark all lines."
-  (interactive)
-  (guix-list-mark-all 'empty))
-
-(defun guix-list-restore-marks ()
-  "Put marks according to `guix-list-marked'."
-  (guix-list-for-each-line
-   (lambda ()
-     (let ((mark-name (car (guix-assq-value guix-list-marked
-                                            (guix-list-current-id)))))
-       (tabulated-list-put-tag
-        (guix-list-get-mark-string (or mark-name 'empty)))))))
-
-(defun guix-list-sort (&optional n)
-  "Sort guix list entries by the column at point.
-With a numeric prefix argument N, sort the Nth column.
-Same as `tabulated-list-sort', but also restore marks after sorting."
-  (interactive "P")
-  (tabulated-list-sort n)
-  (guix-list-restore-marks))
-
-\f
-;;; Major mode and interface definer
-
-(defvar guix-list-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent
-     map (make-composed-keymap guix-buffer-map
-                               tabulated-list-mode-map))
-    (define-key map (kbd "RET") 'guix-list-describe)
-    (define-key map (kbd "i")   'guix-list-describe)
-    (define-key map (kbd "m")   'guix-list-mark)
-    (define-key map (kbd "*")   'guix-list-mark)
-    (define-key map (kbd "u")   'guix-list-unmark)
-    (define-key map (kbd "DEL") 'guix-list-unmark-backward)
-    (define-key map [remap tabulated-list-sort] 'guix-list-sort)
-    map)
-  "Keymap for `guix-list-mode' buffers.")
-
-(define-derived-mode guix-list-mode tabulated-list-mode "Guix-List"
-  "Parent mode for displaying data in 'list' form.")
-
-(defun guix-list-mode-initialize (entry-type)
-  "Set up the current 'list' buffer for displaying ENTRY-TYPE entries."
-  (setq tabulated-list-padding  2
-        tabulated-list-format   (guix-list-tabulated-format entry-type)
-        tabulated-list-sort-key (guix-list-tabulated-sort-key entry-type))
-  (setq-local guix-list-marks   (guix-list-marks entry-type))
-  (tabulated-list-init-header))
-
-(defmacro guix-list-define-interface (entry-type &rest args)
-  "Define 'list' interface for displaying ENTRY-TYPE entries.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-Required keywords:
-
-  - `:format' - default value of the generated
-    `guix-ENTRY-TYPE-list-format' variable.
-
-Optional keywords:
-
-  - `:sort-key' - default value of the generated
-    `guix-ENTRY-TYPE-list-sort-key' variable.
-
-  - `:describe-function' - default value of the generated
-    `guix-ENTRY-TYPE-describe-function' variable.
-
-  - `:list-single?' - default value of the generated
-    `guix-ENTRY-TYPE-list-single' variable.
-
-  - `:marks' - default value of the generated
-    `guix-ENTRY-TYPE-list-marks' variable.
-
-The rest keyword arguments are passed to
-`guix-buffer-define-interface' macro."
-  (declare (indent 1))
-  (let* ((entry-type-str     (symbol-name entry-type))
-         (prefix             (concat "guix-" entry-type-str "-list"))
-         (group              (intern prefix))
-         (describe-var       (intern (concat prefix "-describe-function")))
-         (describe-count-var (intern (concat prefix
-                                             "-describe-warning-count")))
-         (format-var         (intern (concat prefix "-format")))
-         (sort-key-var       (intern (concat prefix "-sort-key")))
-         (list-single-var    (intern (concat prefix "-single")))
-         (marks-var          (intern (concat prefix "-marks"))))
-    (guix-keyword-args-let args
-        ((show-entries-val   :show-entries-function)
-         (describe-val       :describe-function)
-         (describe-count-val :describe-count 10)
-         (format-val         :format)
-         (sort-key-val       :sort-key)
-         (list-single-val    :list-single?)
-         (marks-val          :marks))
-      `(progn
-         (defcustom ,format-var ,format-val
-           ,(format "\
-List of format values of the displayed columns.
-Each element of the list has a form:
-
-  (PARAM VALUE-FUN WIDTH SORT . PROPS)
-
-PARAM is a name of '%s' entry parameter.
-
-VALUE-FUN may be either nil or a function returning a value that
-will be inserted.  The function is called with 2 arguments: the
-first one is the value of the parameter; the second one is an
-entry (alist of parameter names and values).
-
-For the meaning of WIDTH, SORT and PROPS, see
-`tabulated-list-format'."
-                    entry-type-str)
-           :type 'sexp
-           :group ',group)
-
-         (defcustom ,sort-key-var ,sort-key-val
-           ,(format "\
-Default sort key for 'list' buffer with '%s' entries.
-Should be nil (no sort) or have a form:
-
-  (PARAM . FLIP)
-
-PARAM is the name of '%s' entry parameter.  For the meaning of
-FLIP, see `tabulated-list-sort-key'."
-                    entry-type-str entry-type-str)
-           :type '(choice (const :tag "No sort" nil)
-                          (cons symbol boolean))
-           :group ',group)
-
-         (defvar ,marks-var ,marks-val
-           ,(format "\
-Alist of additional marks for 'list' buffer with '%s' entries.
-Marks from this list are used along with `guix-list-default-marks'."
-                    entry-type-str))
-
-         (defcustom ,list-single-var ,list-single-val
-           ,(format "\
-If non-nil, list '%s' entry even if it is the only matching result.
-If nil, show a single '%s' entry in the 'info' buffer."
-                    entry-type-str entry-type-str)
-           :type 'boolean
-           :group ',group)
-
-         (defcustom ,describe-count-var ,describe-count-val
-           ,(format "\
-The maximum number of '%s' entries to describe without a warning.
-If a user wants to describe more than this number of marked
-entries, he will be prompted for confirmation.
-See also `guix-list-describe'."
-                    entry-type-str)
-           :type 'integer
-           :group ',group)
-
-         (defvar ,describe-var ,describe-val
-           ,(format "Function used to describe '%s' entries."
-                    entry-type-str))
-
-         (guix-alist-put!
-          '((describe       . ,describe-var)
-            (describe-count . ,describe-count-var)
-            (format         . ,format-var)
-            (sort-key       . ,sort-key-var)
-            (list-single    . ,list-single-var)
-            (marks          . ,marks-var))
-          'guix-list-data ',entry-type)
-
-         ,(if show-entries-val
-              `(guix-buffer-define-interface list ,entry-type
-                 :show-entries-function ,show-entries-val
-                 ,@%foreign-args)
-
-            (let ((insert-fun    (intern (concat prefix "-insert-entries")))
-                  (mode-init-fun (intern (concat prefix "-mode-initialize"))))
-              `(progn
-                 (defun ,insert-fun (entries)
-                   ,(format "\
-Print '%s' ENTRIES in the current 'list' buffer."
-                            entry-type-str)
-                   (guix-list-insert-entries entries ',entry-type))
-
-                 (defun ,mode-init-fun ()
-                   ,(format "\
-Set up the current 'list' buffer for displaying '%s' entries."
-                            entry-type-str)
-                   (guix-list-mode-initialize ',entry-type))
-
-                 (guix-buffer-define-interface list ,entry-type
-                   :insert-entries-function ',insert-fun
-                   :mode-init-function ',mode-init-fun
-                   ,@%foreign-args))))))))
-
-\f
-(defvar guix-list-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group "guix-list-define-interface")
-            symbol-end)
-       . 1))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-list-font-lock-keywords)
-
-(provide 'guix-list)
-
-;;; guix-list.el ends here
diff --git a/emacs/guix-location.el b/emacs/guix-location.el
deleted file mode 100644
index 81396b4..0000000
--- a/emacs/guix-location.el
+++ /dev/null
@@ -1,79 +0,0 @@
-;;; guix-location.el --- Package locations
-
-;; Copyright © 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public Location as published by
-;; the Free Software Foundation, either version 3 of the Location, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public Location for more details.
-
-;; You should have received a copy of the GNU General Public Location
-;; along with this program.  If not, see <http://www.gnu.org/locations/>.
-
-;;; Commentary:
-
-;; This file provides the code to work with locations of Guix packages.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-backend)
-(require 'guix-read)
-(require 'guix-guile)
-
-(defun guix-package-location (id-or-name)
-  "Return location of a package with ID-OR-NAME.
-For the meaning of location, see `guix-find-location'."
-  (guix-eval-read (guix-make-guile-expression
-                   'package-location-string id-or-name)))
-
-;;;###autoload
-(defun guix-find-location (location &optional directory)
-  "Go to LOCATION of a package.
-LOCATION is a string of the form:
-
-  \"FILE:LINE:COLUMN\"
-
-If FILE is relative, it is considered to be relative to
-DIRECTORY (`guix-directory' by default).
-
-Interactively, prompt for LOCATION.  With prefix argument, prompt
-for DIRECTORY as well."
-  (interactive
-   (list (guix-read-package-location)
-         (guix-read-directory)))
-  (cl-multiple-value-bind (file line column)
-      (split-string location ":")
-    (find-file (expand-file-name file (or directory guix-directory)))
-    (when (and line column)
-      (let ((line   (string-to-number line))
-            (column (string-to-number column)))
-        (goto-char (point-min))
-        (forward-line (- line 1))
-        (move-to-column column)
-        (recenter 1)))))
-
-;;;###autoload
-(defun guix-edit (id-or-name &optional directory)
-  "Edit (go to location of) package with ID-OR-NAME.
-See `guix-find-location' for the meaning of package location and
-DIRECTORY.
-Interactively, with prefix argument, prompt for DIRECTORY."
-  (interactive
-   (list (guix-read-package-name)
-         (guix-read-directory)))
-  (let ((loc (guix-package-location id-or-name)))
-    (if loc
-        (guix-find-location loc directory)
-      (message "Couldn't find package location."))))
-
-(provide 'guix-location)
-
-;;; guix-location.el ends here
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
deleted file mode 100644
index 040932f..0000000
--- a/emacs/guix-main.scm
+++ /dev/null
@@ -1,1163 +0,0 @@
-;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-;;;
-;;; This file is part of GNU Guix.
-;;;
-;;; GNU Guix is free software; you can redistribute it and/or modify it
-;;; under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 3 of the License, or (at
-;;; your option) any later version.
-;;;
-;;; GNU Guix is distributed in the hope that it will be useful, but
-;;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Information about packages and generations is passed to the elisp
-;; side in the form of alists of parameters (such as ‘name’ or
-;; ‘version’) and their values.
-
-;; ‘entries’ procedure is the “entry point” for the elisp side to get
-;; information about packages and generations.
-
-;; Since name/version pair is not necessarily unique, we use
-;; `object-address' to identify a package (for ‘id’ parameter), if
-;; possible.  However for the obsolete packages (that can be found in
-;; installed manifest but not in a package directory), ‘id’ parameter is
-;; still "name-version" string.  So ‘id’ package parameter in the code
-;; below is either an object-address number or a full-name string.
-
-;;; Code:
-
-(use-modules
- (ice-9 vlist)
- (ice-9 match)
- (ice-9 popen)
- (srfi srfi-1)
- (srfi srfi-2)
- (srfi srfi-11)
- (srfi srfi-19)
- (srfi srfi-26)
- (guix)
- (guix combinators)
- (guix git-download)
- (guix grafts)
- (guix packages)
- (guix profiles)
- (guix licenses)
- (guix utils)
- (guix ui)
- (guix scripts)
- (guix scripts package)
- (gnu packages)
- (gnu system))
-
-(define-syntax-rule (first-or-false lst)
-  (and (not (null? lst))
-       (first lst)))
-
-(define (list-maybe obj)
-  (if (list? obj) obj (list obj)))
-
-(define (output+error thunk)
-  "Call THUNK and return 2 values: output and error output as strings."
-  (let ((output-port (open-output-string))
-        (error-port  (open-output-string)))
-    (with-output-to-port output-port
-      (lambda () (with-error-to-port error-port thunk)))
-    (let ((strings (list (get-output-string output-port)
-                         (get-output-string error-port))))
-      (close-output-port output-port)
-      (close-output-port error-port)
-      (apply values strings))))
-
-(define (full-name->name+version spec)
-  "Given package specification SPEC with or without output,
-return two values: name and version.  For example, for SPEC
-\"foo@0.9.1b:lib\", return \"foo\" and \"0.9.1b\"."
-  (let-values (((name version output)
-                (package-specification->name+version+output spec)))
-    (values name version)))
-
-(define (name+version->full-name name version)
-  (string-append name "@" version))
-
-(define* (make-package-specification name #:optional version output)
-  (let ((full-name (if version
-                       (name+version->full-name name version)
-                       name)))
-    (if output
-        (string-append full-name ":" output)
-        full-name)))
-
-(define (manifest-entry->name+version+output entry)
-  (values
-   (manifest-entry-name    entry)
-   (manifest-entry-version entry)
-   (manifest-entry-output  entry)))
-
-(define (manifest-entry->package-specification entry)
-  (call-with-values
-      (lambda () (manifest-entry->name+version+output entry))
-    make-package-specification))
-
-(define (manifest-entries->package-specifications entries)
-  (map manifest-entry->package-specification entries))
-
-(define (profile-package-specifications profile)
-  "Return a list of package specifications for PROFILE."
-  (let ((manifest (profile-manifest profile)))
-    (manifest-entries->package-specifications
-     (manifest-entries manifest))))
-
-(define (profile->specifications+paths profile)
-  "Return a list of package specifications and paths for PROFILE.
-Each element of the list is a list of the package specification and its path."
-  (let ((manifest (profile-manifest profile)))
-    (map (lambda (entry)
-           (list (manifest-entry->package-specification entry)
-                 (manifest-entry-item entry)))
-         (manifest-entries manifest))))
-
-(define (profile-difference profile1 profile2)
-  "Return a list of package specifications for outputs installed in PROFILE1
-and not installed in PROFILE2."
-  (let ((specs1 (profile-package-specifications profile1))
-        (specs2 (profile-package-specifications profile2)))
-    (lset-difference string=? specs1 specs2)))
-
-(define (manifest-entries->hash-table entries)
-  "Return a hash table of name keys and lists of matching manifest ENTRIES."
-  (let ((table (make-hash-table (length entries))))
-    (for-each (lambda (entry)
-                (let* ((key (manifest-entry-name entry))
-                       (ref (hash-ref table key)))
-                  (hash-set! table key
-                             (if ref (cons entry ref) (list entry)))))
-              entries)
-    table))
-
-(define (manifest=? m1 m2)
-  (or (eq? m1 m2)
-      (equal? m1 m2)))
-
-(define manifest->hash-table
-  (let ((current-manifest #f)
-        (current-table #f))
-    (lambda (manifest)
-      "Return a hash table of name keys and matching MANIFEST entries."
-      (unless (manifest=? manifest current-manifest)
-        (set! current-manifest manifest)
-        (set! current-table (manifest-entries->hash-table
-                             (manifest-entries manifest))))
-      current-table)))
-
-(define* (manifest-entries-by-name manifest name #:optional version output)
-  "Return a list of MANIFEST entries matching NAME, VERSION and OUTPUT."
-  (let ((entries (or (hash-ref (manifest->hash-table manifest) name)
-                     '())))
-    (if (or version output)
-        (filter (lambda (entry)
-                  (and (or (not version)
-                           (equal? version (manifest-entry-version entry)))
-                       (or (not output)
-                           (equal? output  (manifest-entry-output entry)))))
-                entries)
-        entries)))
-
-(define (manifest-entry-by-output entries output)
-  "Return a manifest entry from ENTRIES matching OUTPUT."
-  (find (lambda (entry)
-          (string= output (manifest-entry-output entry)))
-        entries))
-
-(define (fold-manifest-by-name manifest proc init)
-  "Fold over MANIFEST entries.
-Call (PROC NAME VERSION ENTRIES RESULT), using INIT as the initial value
-of RESULT.  ENTRIES is a list of manifest entries with NAME/VERSION."
-  (hash-fold (lambda (name entries res)
-               (proc name (manifest-entry-version (car entries))
-                     entries res))
-             init
-             (manifest->hash-table manifest)))
-
-(define* (object-transformer param-alist #:optional (params '()))
-  "Return procedure transforming objects into alist of parameter/value pairs.
-
-PARAM-ALIST is alist of available parameters (symbols) and procedures
-returning values of these parameters.  Each procedure is applied to
-objects.
-
-PARAMS is list of parameters from PARAM-ALIST that should be returned by
-a resulting procedure.  If PARAMS is not specified or is an empty list,
-use all available parameters.
-
-Example:
-
-  (let* ((alist `((plus1 . ,1+) (minus1 . ,1-) (mul2 . ,(cut * 2 <>))))
-         (number->alist (object-transformer alist '(plus1 mul2))))
-    (number->alist 8))
-  =>
-  ((plus1 . 9) (mul2 . 16))
-"
-  (let* ((use-all-params (null? params))
-         (alist (filter-map (match-lambda
-                             ((param . proc)
-                              (and (or use-all-params
-                                       (memq param params))
-                                   (cons param proc)))
-                             (_ #f))
-                            param-alist)))
-    (lambda objects
-      (map (match-lambda
-            ((param . proc)
-             (cons param (apply proc objects))))
-           alist))))
-
-(define %manifest-entry-param-alist
-  `((output       . ,manifest-entry-output)
-    (path         . ,manifest-entry-item)
-    (dependencies . ,manifest-entry-dependencies)))
-
-(define manifest-entry->sexp
-  (object-transformer %manifest-entry-param-alist))
-
-(define (manifest-entries->sexps entries)
-  (map manifest-entry->sexp entries))
-
-(define (package-inputs-names inputs)
-  "Return a list of full names of the packages from package INPUTS."
-  (filter-map (match-lambda
-               ((_ (? package? package))
-                (make-package-specification (package-name package)
-                                            (package-version package)))
-               ((_ (? package? package) output)
-                (make-package-specification (package-name package)
-                                            (package-version package)
-                                            output))
-               (_ #f))
-              inputs))
-
-(define (package-license-names package)
-  "Return a list of license names of the PACKAGE."
-  (filter-map (lambda (license)
-                (and (license? license)
-                     (license-name license)))
-              (list-maybe (package-license package))))
-
-(define (package-source-names package)
-  "Return a list of source names (URLs) of the PACKAGE."
-  (let ((source (package-source package)))
-    (and (origin? source)
-         (filter-map (lambda (uri)
-                       (cond ((string? uri)
-                              uri)
-                             ((git-reference? uri)
-                              (git-reference-url uri))
-                             (else "Unknown source type")))
-                     (list-maybe (origin-uri source))))))
-
-(define (package-unique? package)
-  "Return #t if PACKAGE is a single package with such name/version."
-  (match (packages-by-name (package-name package)
-                           (package-version package))
-    ((package) #t)
-    (_ #f)))
-
-(define %package-param-alist
-  `((id                . ,object-address)
-    (package-id        . ,object-address)
-    (name              . ,package-name)
-    (version           . ,package-version)
-    (license           . ,package-license-names)
-    (source            . ,package-source-names)
-    (synopsis          . ,package-synopsis)
-    (description       . ,package-description-string)
-    (home-url          . ,package-home-page)
-    (outputs           . ,package-outputs)
-    (systems           . ,package-supported-systems)
-    (non-unique        . ,(negate package-unique?))
-    (inputs            . ,(lambda (pkg)
-                            (package-inputs-names
-                             (package-inputs pkg))))
-    (native-inputs     . ,(lambda (pkg)
-                            (package-inputs-names
-                             (package-native-inputs pkg))))
-    (propagated-inputs . ,(lambda (pkg)
-                            (package-inputs-names
-                             (package-propagated-inputs pkg))))
-    (location          . ,(lambda (pkg)
-                            (location->string (package-location pkg))))))
-
-(define (package-param package param)
-  "Return a value of a PACKAGE PARAM."
-  (and=> (assq-ref %package-param-alist param)
-         (cut <> package)))
-
-\f
-;;; Finding packages.
-
-(define-values (package-by-address
-                register-package)
-  (let ((table (delay (fold-packages
-                       (lambda (package table)
-                         (vhash-consq (object-address package)
-                                      package table))
-                       vlist-null))))
-    (values
-     (lambda (address)
-       "Return package by its object ADDRESS."
-       (match (vhash-assq address (force table))
-         ((_ . package) package)
-         (_ #f)))
-     (lambda (package)
-       "Register PACKAGE by its 'object-address', so that later
-'package-by-address' can be used to access it."
-       (let ((table* (force table)))
-         (set! table
-               (delay (vhash-consq (object-address package)
-                                   package table*))))))))
-
-(define packages-by-name+version
-  (let ((table (delay (fold-packages
-                       (lambda (package table)
-                         (let ((file (location-file
-                                      (package-location package))))
-                           (vhash-cons (cons (package-name package)
-                                             (package-version package))
-                                       package table)))
-                       vlist-null))))
-    (lambda (name version)
-      "Return packages matching NAME and VERSION."
-      (vhash-fold* cons '() (cons name version) (force table)))))
-
-(define (packages-by-full-name full-name)
-  (call-with-values
-      (lambda () (full-name->name+version full-name))
-    packages-by-name+version))
-
-(define (packages-by-id id)
-  (if (integer? id)
-      (let ((pkg (package-by-address id)))
-        (if pkg (list pkg) '()))
-      (packages-by-full-name id)))
-
-(define (id->name+version id)
-  (if (integer? id)
-      (and=> (package-by-address id)
-             (lambda (pkg)
-               (values (package-name pkg)
-                       (package-version pkg))))
-      (full-name->name+version id)))
-
-(define (package-by-id id)
-  (first-or-false (packages-by-id id)))
-
-(define (newest-package-by-id id)
-  (and=> (id->name+version id)
-         (lambda (name)
-           (first-or-false (find-best-packages-by-name name #f)))))
-
-(define (matching-packages predicate)
-  (fold-packages (lambda (pkg res)
-                   (if (predicate pkg)
-                       (cons pkg res)
-                       res))
-                 '()))
-
-(define (filter-packages-by-output packages output)
-  (filter (lambda (package)
-            (member output (package-outputs package)))
-          packages))
-
-(define* (packages-by-name name #:optional version output)
-  "Return a list of packages matching NAME, VERSION and OUTPUT."
-  (let ((packages (if version
-                      (packages-by-name+version name version)
-                      (matching-packages
-                       (lambda (pkg) (string=? name (package-name pkg)))))))
-    (if output
-        (filter-packages-by-output packages output)
-        packages)))
-
-(define (manifest-entry->packages entry)
-  (call-with-values
-      (lambda () (manifest-entry->name+version+output entry))
-    packages-by-name))
-
-(define (packages-by-regexp regexp match-params)
-  "Return a list of packages matching REGEXP string.
-MATCH-PARAMS is a list of parameters that REGEXP can match."
-  (define (package-match? package regexp)
-    (any (lambda (param)
-           (let ((val (package-param package param)))
-             (and (string? val) (regexp-exec regexp val))))
-         match-params))
-
-  (let ((re (make-regexp regexp regexp/icase)))
-    (matching-packages (cut package-match? <> re))))
-
-(define (packages-by-license license)
-  "Return a list of packages with LICENSE."
-  (matching-packages
-   (lambda (package)
-     (memq license (list-maybe (package-license package))))))
-
-(define (all-available-packages)
-  "Return a list of all available packages."
-  (matching-packages (const #t)))
-
-(define (newest-available-packages)
-  "Return a list of the newest available packages."
-  (vhash-fold (lambda (name elem res)
-                (match elem
-                  ((_ newest pkgs ...)
-                   (cons newest res))))
-              '()
-              (find-newest-available-packages)))
-
-(define (packages-from-file file)
-  "Return a list of packages from FILE."
-  (let ((package (load (canonicalize-path file))))
-    (if (package? package)
-        (begin
-          (register-package package)
-          (list package))
-        '())))
-
-\f
-;;; Making package/output patterns.
-
-(define (specification->package-pattern specification)
-  (call-with-values
-      (lambda ()
-        (full-name->name+version specification))
-    list))
-
-(define (specification->output-pattern specification)
-  (call-with-values
-      (lambda ()
-        (package-specification->name+version+output specification #f))
-    list))
-
-(define (id->package-pattern id)
-  (if (integer? id)
-      (package-by-address id)
-      (specification->package-pattern id)))
-
-(define (id->output-pattern id)
-  "Return an output pattern by output ID.
-ID should be '<package-address>:<output>' or '<name>-<version>:<output>'."
-  (let-values (((name version output)
-                (package-specification->name+version+output id)))
-    (if version
-        (list name version output)
-        (list (package-by-address (string->number name))
-              output))))
-
-(define (specifications->package-patterns . specifications)
-  (map specification->package-pattern specifications))
-
-(define (specifications->output-patterns . specifications)
-  (map specification->output-pattern specifications))
-
-(define (ids->package-patterns . ids)
-  (map id->package-pattern ids))
-
-(define (ids->output-patterns . ids)
-  (map id->output-pattern ids))
-
-(define* (manifest-patterns-result packages res obsolete-pattern
-                                   #:optional installed-pattern)
-  "Auxiliary procedure for 'manifest-package-patterns' and
-'manifest-output-patterns'."
-  (if (null? packages)
-      (cons (obsolete-pattern) res)
-      (if installed-pattern
-          ;; We don't need duplicates for a list of installed packages,
-          ;; so just take any (car) package.
-          (cons (installed-pattern (car packages)) res)
-          res)))
-
-(define* (manifest-package-patterns manifest #:optional obsolete-only?)
-  "Return a list of package patterns for MANIFEST entries.
-If OBSOLETE-ONLY? is #f, use all entries, otherwise make patterns only
-for obsolete packages."
-  (fold-manifest-by-name
-   manifest
-   (lambda (name version entries res)
-     (manifest-patterns-result (packages-by-name name version)
-                               res
-                               (lambda () (list name version entries))
-                               (and (not obsolete-only?)
-                                    (cut list <> entries))))
-   '()))
-
-(define* (manifest-output-patterns manifest #:optional obsolete-only?)
-  "Return a list of output patterns for MANIFEST entries.
-If OBSOLETE-ONLY? is #f, use all entries, otherwise make patterns only
-for obsolete packages."
-  (fold (lambda (entry res)
-          (manifest-patterns-result (manifest-entry->packages entry)
-                                    res
-                                    (lambda () entry)
-                                    (and (not obsolete-only?)
-                                         (cut list <> entry))))
-        '()
-        (manifest-entries manifest)))
-
-(define (obsolete-package-patterns manifest)
-  (manifest-package-patterns manifest #t))
-
-(define (obsolete-output-patterns manifest)
-  (manifest-output-patterns manifest #t))
-
-\f
-;;; Transforming package/output patterns into alists.
-
-(define (obsolete-package-sexp name version entries)
-  "Return an alist with information about obsolete package.
-ENTRIES is a list of installed manifest entries."
-  `((id        . ,(name+version->full-name name version))
-    (name      . ,name)
-    (version   . ,version)
-    (outputs   . ,(map manifest-entry-output entries))
-    (obsolete  . #t)
-    (installed . ,(manifest-entries->sexps entries))))
-
-(define (package-pattern-transformer manifest params)
-  "Return 'package-pattern->package-sexps' procedure."
-  (define package->sexp
-    (object-transformer %package-param-alist params))
-
-  (define* (sexp-by-package package #:optional
-                            (entries (manifest-entries-by-name
-                                      manifest
-                                      (package-name package)
-                                      (package-version package))))
-    (cons (cons 'installed (manifest-entries->sexps entries))
-          (package->sexp package)))
-
-  (define (->sexps pattern)
-    (match pattern
-      ((? package? package)
-       (list (sexp-by-package package)))
-      (((? package? package) entries)
-       (list (sexp-by-package package entries)))
-      ((name version entries)
-       (list (obsolete-package-sexp
-              name version entries)))
-      ((name version)
-       (let ((packages (packages-by-name name version)))
-         (if (null? packages)
-             (let ((entries (manifest-entries-by-name
-                             manifest name version)))
-               (if (null? entries)
-                   '()
-                   (list (obsolete-package-sexp
-                          name version entries))))
-             (map sexp-by-package packages))))
-      (_ '())))
-
-  ->sexps)
-
-(define (output-pattern-transformer manifest params)
-  "Return 'output-pattern->output-sexps' procedure."
-  (define package->sexp
-    (object-transformer (alist-delete 'id %package-param-alist)
-                        params))
-
-  (define manifest-entry->sexp
-    (object-transformer (alist-delete 'output %manifest-entry-param-alist)
-                        params))
-
-  (define* (output-sexp pkg-alist pkg-address output
-                        #:optional entry)
-    (let ((entry-alist (if entry
-                           (manifest-entry->sexp entry)
-                           '()))
-          (base `((id        . ,(string-append
-                                 (number->string pkg-address)
-                                 ":" output))
-                  (output    . ,output)
-                  (installed . ,(->bool entry)))))
-      (append entry-alist base pkg-alist)))
-
-  (define (obsolete-output-sexp entry)
-    (let-values (((name version output)
-                  (manifest-entry->name+version+output entry)))
-      (let ((base `((id         . ,(make-package-specification
-                                    name version output))
-                    (package-id . ,(name+version->full-name name version))
-                    (name       . ,name)
-                    (version    . ,version)
-                    (output     . ,output)
-                    (obsolete   . #t)
-                    (installed  . #t))))
-        (append (manifest-entry->sexp entry) base))))
-
-  (define* (sexps-by-package package #:optional output
-                             (entries (manifest-entries-by-name
-                                       manifest
-                                       (package-name package)
-                                       (package-version package))))
-    ;; Assuming that PACKAGE has this OUTPUT.
-    (let ((pkg-alist (package->sexp package))
-          (address (object-address package))
-          (outputs (if output
-                       (list output)
-                       (package-outputs package))))
-      (map (lambda (output)
-             (output-sexp pkg-alist address output
-                          (manifest-entry-by-output entries output)))
-           outputs)))
-
-  (define* (sexps-by-manifest-entry entry #:optional
-                                    (packages (manifest-entry->packages
-                                               entry)))
-    (if (null? packages)
-        (list (obsolete-output-sexp entry))
-        (map (lambda (package)
-               (output-sexp (package->sexp package)
-                            (object-address package)
-                            (manifest-entry-output entry)
-                            entry))
-             packages)))
-
-  (define (->sexps pattern)
-    (match pattern
-      ((? package? package)
-       (sexps-by-package package))
-      ((package (? string? output))
-       (sexps-by-package package output))
-      ((? manifest-entry? entry)
-       (list (obsolete-output-sexp entry)))
-      ((package entry)
-       (sexps-by-manifest-entry entry (list package)))
-      ((name version output)
-       (let ((packages (packages-by-name name version output)))
-         (if (null? packages)
-             (let ((entries (manifest-entries-by-name
-                             manifest name version output)))
-               (append-map (cut sexps-by-manifest-entry <>)
-                           entries))
-             (append-map (cut sexps-by-package <> output)
-                         packages))))
-      (_ '())))
-
-  ->sexps)
-
-(define (entry-type-error entry-type)
-  (error (format #f "Wrong entry-type '~a'" entry-type)))
-
-(define (search-type-error entry-type search-type)
-  (error (format #f "Wrong search type '~a' for entry-type '~a'"
-                 search-type entry-type)))
-
-(define %pattern-transformers
-  `((package . ,package-pattern-transformer)
-    (output  . ,output-pattern-transformer)))
-
-(define (pattern-transformer entry-type)
-  (assq-ref %pattern-transformers entry-type))
-
-;; All procedures from inner alists are called with (MANIFEST . SEARCH-VALS)
-;; as arguments; see `package/output-sexps'.
-(define %patterns-makers
-  (let* ((apply-to-rest         (lambda (proc)
-                                  (lambda (_ . rest) (apply proc rest))))
-         (apply-to-first        (lambda (proc)
-                                  (lambda (first . _) (proc first))))
-         (manifest-package-proc (apply-to-first manifest-package-patterns))
-         (manifest-output-proc  (apply-to-first manifest-output-patterns))
-         (regexp-proc           (lambda (_ regexp params . __)
-                                  (packages-by-regexp regexp params)))
-         (license-proc          (lambda (_ license-name)
-                                  (packages-by-license
-                                   (lookup-license license-name))))
-         (location-proc         (lambda (_ location)
-                                  (packages-by-location-file location)))
-         (file-proc             (lambda (_ file)
-                                  (packages-from-file file)))
-         (all-proc              (lambda _ (all-available-packages)))
-         (newest-proc           (lambda _ (newest-available-packages))))
-    `((package
-       (id               . ,(apply-to-rest ids->package-patterns))
-       (name             . ,(apply-to-rest specifications->package-patterns))
-       (installed        . ,manifest-package-proc)
-       (obsolete         . ,(apply-to-first obsolete-package-patterns))
-       (regexp           . ,regexp-proc)
-       (license          . ,license-proc)
-       (location         . ,location-proc)
-       (from-file        . ,file-proc)
-       (all-available    . ,all-proc)
-       (newest-available . ,newest-proc))
-      (output
-       (id               . ,(apply-to-rest ids->output-patterns))
-       (name             . ,(apply-to-rest specifications->output-patterns))
-       (installed        . ,manifest-output-proc)
-       (obsolete         . ,(apply-to-first obsolete-output-patterns))
-       (regexp           . ,regexp-proc)
-       (license          . ,license-proc)
-       (location         . ,location-proc)
-       (from-file        . ,file-proc)
-       (all-available    . ,all-proc)
-       (newest-available . ,newest-proc)))))
-
-(define (patterns-maker entry-type search-type)
-  (or (and=> (assq-ref %patterns-makers entry-type)
-             (cut assq-ref <> search-type))
-      (search-type-error entry-type search-type)))
-
-(define (package/output-sexps profile params entry-type
-                              search-type search-vals)
-  "Return information about packages or package outputs.
-See 'entry-sexps' for details."
-  (let* ((manifest (profile-manifest profile))
-         (patterns (if (and (eq? entry-type 'output)
-                            (eq? search-type 'profile-diff))
-                       (match search-vals
-                         ((p1 p2)
-                          (map specification->output-pattern
-                               (profile-difference p1 p2)))
-                         (_ '()))
-                       (apply (patterns-maker entry-type search-type)
-                              manifest search-vals)))
-         (->sexps ((pattern-transformer entry-type) manifest params)))
-    (append-map ->sexps patterns)))
-
-\f
-;;; Getting information about generations.
-
-(define (generation-param-alist profile)
-  "Return an alist of generation parameters and procedures for PROFILE."
-  (let ((current (generation-number profile)))
-    `((id          . ,identity)
-      (number      . ,identity)
-      (prev-number . ,(cut previous-generation-number profile <>))
-      (current     . ,(cut = current <>))
-      (path        . ,(cut generation-file-name profile <>))
-      (time        . ,(lambda (gen)
-                        (time-second (generation-time profile gen)))))))
-
-(define (matching-generations profile predicate)
-  "Return a list of PROFILE generations matching PREDICATE."
-  (filter predicate (profile-generations profile)))
-
-(define (last-generations profile number)
-  "Return a list of last NUMBER generations.
-If NUMBER is 0 or less, return all generations."
-  (let ((generations (profile-generations profile))
-        (number (if (<= number 0) +inf.0 number)))
-    (if (> (length generations) number)
-        (list-head  (reverse generations) number)
-        generations)))
-
-(define (find-generations profile search-type search-vals)
-  "Find PROFILE's generations matching SEARCH-TYPE and SEARCH-VALS."
-  (case search-type
-    ((id)
-     (matching-generations profile (cut memq <> search-vals)))
-    ((last)
-     (last-generations profile (car search-vals)))
-    ((all)
-     (last-generations profile +inf.0))
-    ((time)
-     (match search-vals
-       ((from to)
-        (matching-generations
-         profile
-         (lambda (gen)
-           (let ((time (time-second (generation-time profile gen))))
-             (< from time to)))))
-       (_ '())))
-    (else (search-type-error "generation" search-type))))
-
-(define (generation-sexps profile params search-type search-vals)
-  "Return information about generations.
-See 'entry-sexps' for details."
-  (let ((generations (find-generations profile search-type search-vals))
-        (->sexp (object-transformer (generation-param-alist profile)
-                                    params)))
-    (map ->sexp generations)))
-
-(define system-generation-boot-parameters
-  (memoize
-   (lambda (profile generation)
-     "Return boot parameters for PROFILE's system GENERATION."
-     (let* ((gen-file   (generation-file-name profile generation))
-            (param-file (string-append gen-file "/parameters")))
-       (call-with-input-file param-file read-boot-parameters)))))
-
-(define (system-generation-param-alist profile)
-  "Return an alist of system generation parameters and procedures for
-PROFILE."
-  (append (generation-param-alist profile)
-          `((label       . ,(lambda (gen)
-                              (boot-parameters-label
-                               (system-generation-boot-parameters
-                                profile gen))))
-            (root-device . ,(lambda (gen)
-                              (boot-parameters-root-device
-                               (system-generation-boot-parameters
-                                profile gen))))
-            (kernel      . ,(lambda (gen)
-                              (boot-parameters-kernel
-                               (system-generation-boot-parameters
-                                profile gen)))))))
-
-(define (system-generation-sexps profile params search-type search-vals)
-  "Return an alist with information about system generations."
-  (let ((generations (find-generations profile search-type search-vals))
-        (->sexp (object-transformer (system-generation-param-alist profile)
-                                    params)))
-    (map ->sexp generations)))
-
-\f
-;;; Getting package/output/generation entries (alists).
-
-(define (entries profile params entry-type search-type search-vals)
-  "Return information about entries.
-
-ENTRY-TYPE is a symbol defining a type of returning information.  Should
-be: 'package', 'output' or 'generation'.
-
-SEARCH-TYPE and SEARCH-VALS define how to get the information.
-SEARCH-TYPE should be one of the following symbols:
-
-- If ENTRY-TYPE is 'package' or 'output':
-  'id', 'name', 'regexp', 'all-available', 'newest-available',
-  'installed', 'obsolete', 'generation'.
-
-- If ENTRY-TYPE is 'generation':
-  'id', 'last', 'all', 'time'.
-
-PARAMS is a list of parameters for receiving.  If it is an empty list,
-get information with all available parameters, which are:
-
-- If ENTRY-TYPE is 'package':
-  'id', 'name', 'version', 'outputs', 'license', 'synopsis',
-  'description', 'home-url', 'inputs', 'native-inputs',
-  'propagated-inputs', 'location', 'installed'.
-
-- If ENTRY-TYPE is 'output':
-  'id', 'package-id', 'name', 'version', 'output', 'license',
-  'synopsis', 'description', 'home-url', 'inputs', 'native-inputs',
-  'propagated-inputs', 'location', 'installed', 'path', 'dependencies'.
-
-- If ENTRY-TYPE is 'generation':
-  'id', 'number', 'prev-number', 'path', 'time'.
-
-Returning value is a list of alists.  Each alist consists of
-parameter/value pairs."
-  (case entry-type
-    ((package output)
-     (package/output-sexps profile params entry-type
-                           search-type search-vals))
-    ((generation)
-     (generation-sexps profile params
-                       search-type search-vals))
-    ((system-generation)
-     (system-generation-sexps profile params
-                              search-type search-vals))
-    (else (entry-type-error entry-type))))
-
-\f
-;;; Package actions.
-
-(define* (package->manifest-entry* package #:optional output)
-  (and package
-       (package->manifest-entry package output)))
-
-(define* (make-install-manifest-entries id #:optional output)
-  (package->manifest-entry* (package-by-id id) output))
-
-(define* (make-upgrade-manifest-entries id #:optional output)
-  (package->manifest-entry* (newest-package-by-id id) output))
-
-(define* (make-manifest-pattern id #:optional output)
-  "Make manifest pattern from a package ID and OUTPUT."
-  (let-values (((name version)
-                (id->name+version id)))
-    (and name version
-         (manifest-pattern
-          (name name)
-          (version version)
-          (output output)))))
-
-(define (convert-action-pattern pattern proc)
-  "Convert action PATTERN into a list of objects returned by PROC.
-PROC is called: (PROC ID) or (PROC ID OUTPUT)."
-  (match pattern
-    ((id . outputs)
-     (if (null? outputs)
-         (let ((obj (proc id)))
-           (if obj (list obj) '()))
-         (filter-map (cut proc id <>)
-                     outputs)))
-    (_ '())))
-
-(define (convert-action-patterns patterns proc)
-  (append-map (cut convert-action-pattern <> proc)
-              patterns))
-
-(define* (process-package-actions
-          profile #:key (install '()) (upgrade '()) (remove '())
-          (use-substitutes? #t) dry-run?)
-  "Perform package actions.
-
-INSTALL, UPGRADE, REMOVE are lists of 'package action patterns'.
-Each pattern should have the following form:
-
-  (ID . OUTPUTS)
-
-ID is an object address or a full-name of a package.
-OUTPUTS is a list of package outputs (may be an empty list)."
-  (format #t "The process begins ...~%")
-  (let* ((install (append
-                   (convert-action-patterns
-                    install make-install-manifest-entries)
-                   (convert-action-patterns
-                    upgrade make-upgrade-manifest-entries)))
-         (remove (convert-action-patterns remove make-manifest-pattern))
-         (transaction (manifest-transaction (install install)
-                                            (remove remove)))
-         (manifest (profile-manifest profile))
-         (new-manifest (manifest-perform-transaction
-                        manifest transaction)))
-    (unless (and (null? install) (null? remove))
-      (parameterize ((%graft? (not dry-run?)))
-        (with-store store
-          (set-build-options store
-                             #:print-build-trace #f
-                             #:use-substitutes? use-substitutes?)
-          (show-manifest-transaction store manifest transaction
-                                     #:dry-run? dry-run?)
-          (build-and-use-profile store profile new-manifest
-                                 #:use-substitutes? use-substitutes?
-                                 #:dry-run? dry-run?))))))
-
-(define (delete-generations* profile generations)
-  "Delete GENERATIONS from PROFILE.
-GENERATIONS is a list of generation numbers."
-  (with-store store
-    (delete-generations store profile generations)))
-
-(define (package-location-string id-or-name)
-  "Return a location string of a package with ID-OR-NAME."
-  (and=> (or (package-by-id id-or-name)
-             (match (packages-by-name id-or-name)
-               (()              #f)
-               ((package _ ...) package)))
-         (compose location->string package-location)))
-
-(define (package-store-path package-id)
-  "Return a list of store directories of outputs of package PACKAGE-ID."
-  (match (package-by-id package-id)
-    (#f '())
-    (package
-      (with-store store
-        (map (match-lambda
-               ((_ . drv)
-                (derivation-output-path drv)))
-             (derivation-outputs (package-derivation store package)))))))
-
-(define (package-source-derivation->store-path derivation)
-  "Return a store path of the package source DERIVATION."
-  (match (derivation-outputs derivation)
-    ;; Source derivation is always (("out" . derivation)).
-    (((_ . output-drv))
-     (derivation-output-path output-drv))
-    (_ #f)))
-
-(define (package-source-path package-id)
-  "Return a store file path to a source of a package PACKAGE-ID."
-  (and-let* ((package (package-by-id package-id))
-             (source  (package-source package)))
-    (with-store store
-      (package-source-derivation->store-path
-       (package-source-derivation store source)))))
-
-(define* (package-source-build-derivation package-id #:key dry-run?
-                                          (use-substitutes? #t))
-  "Build source derivation of a package PACKAGE-ID."
-  (and-let* ((package (package-by-id package-id))
-             (source  (package-source package)))
-    (with-store store
-      (let* ((derivation  (package-source-derivation store source))
-             (derivations (list derivation)))
-        (set-build-options store
-                           #:print-build-trace #f
-                           #:use-substitutes? use-substitutes?)
-        (show-what-to-build store derivations
-                            #:use-substitutes? use-substitutes?
-                            #:dry-run? dry-run?)
-        (unless dry-run?
-          (build-derivations store derivations))
-        (format #t "The source store path: ~a~%"
-                (package-source-derivation->store-path derivation))))))
-
-(define (package-build-log-file package-id)
-  "Return the build log file of a package PACKAGE-ID.
-Return #f if the build log is not found."
-  (and-let* ((package (package-by-id package-id)))
-    (with-store store
-      (let* ((derivation (package-derivation store package))
-             (file       (derivation-file-name derivation)))
-        (or (log-file store file)
-            ((@@ (guix scripts build) log-url) store file))))))
-
-\f
-;;; Executing guix commands
-
-(define (guix-command . args)
-  "Run 'guix ARGS ...' command."
-  (catch 'quit
-    (lambda () (apply run-guix args))
-    (const #t)))
-
-(define (guix-command-output . args)
-  "Return 2 strings with 'guix ARGS ...' output and error output."
-  (output+error
-   (lambda ()
-     (parameterize ((guix-warning-port (current-error-port)))
-       (apply guix-command args)))))
-
-(define (help-string . commands)
-  "Return string with 'guix COMMANDS ... --help' output."
-  (apply guix-command-output `(,@commands "--help")))
-
-(define (pipe-guix-output guix-args command-args)
-  "Run 'guix GUIX-ARGS ...' command and pipe its output to a shell command
-defined by COMMAND-ARGS.
-Return #t if the shell command was executed successfully."
-  (let ((pipe (apply open-pipe* OPEN_WRITE command-args)))
-    (with-output-to-port pipe
-      (lambda () (apply guix-command guix-args)))
-    (zero? (status:exit-val (close-pipe pipe)))))
-
-\f
-;;; Lists of packages, lint checkers, etc.
-
-(define (graph-type-names)
-  "Return a list of names of available graph node types."
-  (map (@ (guix graph) node-type-name)
-       (@ (guix scripts graph) %node-types)))
-
-(define (refresh-updater-names)
-  "Return a list of names of available refresh updater types."
-  (map (@ (guix upstream) upstream-updater-name)
-       (@ (guix scripts refresh) %updaters)))
-
-(define (lint-checker-names)
-  "Return a list of names of available lint checkers."
-  (map (lambda (checker)
-         (symbol->string ((@ (guix scripts lint) lint-checker-name)
-                          checker)))
-       (@ (guix scripts lint) %checkers)))
-
-(define (package-names)
-  "Return a list of names of available packages."
-  (delete-duplicates
-   (fold-packages (lambda (pkg res)
-                    (cons (package-name pkg) res))
-                  '())))
-
-;; See the comment to 'guix-package-names' function in "guix-popup.el".
-(define (package-names-lists)
-  (map list (package-names)))
-
-\f
-;;; Licenses
-
-(define %licenses
-  (delay
-    (filter license?
-            (module-map (lambda (_ var)
-                          (variable-ref var))
-                        (resolve-interface '(guix licenses))))))
-
-(define (licenses)
-  (force %licenses))
-
-(define (license-names)
-  "Return a list of names of available licenses."
-  (map license-name (licenses)))
-
-(define lookup-license
-  (memoize
-   (lambda (name)
-     "Return a license by its name."
-     (find (lambda (l)
-             (string=? name (license-name l)))
-           (licenses)))))
-
-(define (lookup-license-uri name)
-  "Return a license URI by its name."
-  (and=> (lookup-license name)
-         license-uri))
-
-(define %license-param-alist
-  `((id      . ,license-name)
-    (name    . ,license-name)
-    (url     . ,license-uri)
-    (comment . ,license-comment)))
-
-(define license->sexp
-  (object-transformer %license-param-alist))
-
-(define (find-licenses search-type . search-values)
-  "Return a list of licenses depending on SEARCH-TYPE and SEARCH-VALUES."
-  (case search-type
-    ((id name)
-     (let ((names search-values))
-       (filter-map lookup-license names)))
-    ((all)
-     (licenses))))
-
-(define (license-entries search-type . search-values)
-  (map license->sexp
-       (apply find-licenses search-type search-values)))
-
-\f
-;;; Package locations
-
-(define-values (packages-by-location-file
-                package-location-files)
-  (let* ((table (delay (fold-packages
-                        (lambda (package table)
-                          (let ((file (location-file
-                                       (package-location package))))
-                            (vhash-cons file package table)))
-                        vlist-null)))
-         (files (delay (vhash-fold
-                        (lambda (file _ result)
-                          (if (member file result)
-                              result
-                              (cons file result)))
-                        '()
-                        (force table)))))
-    (values
-     (lambda (file)
-       "Return the (possibly empty) list of packages defined in location FILE."
-       (vhash-fold* cons '() file (force table)))
-     (lambda ()
-       "Return the list of file names of all package locations."
-       (force files)))))
-
-(define %package-location-param-alist
-  `((id       . ,identity)
-    (location . ,identity)
-    (number-of-packages . ,(lambda (location)
-                             (length (packages-by-location-file location))))))
-
-(define package-location->sexp
-  (object-transformer %package-location-param-alist))
-
-(define (package-location-entries)
-  (map package-location->sexp (package-location-files)))
diff --git a/emacs/guix-messages.el b/emacs/guix-messages.el
deleted file mode 100644
index 52436af..0000000
--- a/emacs/guix-messages.el
+++ /dev/null
@@ -1,247 +0,0 @@
-;;; guix-messages.el --- Minibuffer messages
-
-;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides `guix-result-message' function used to show a
-;; minibuffer message after displaying packages/generations in a
-;; list/info buffer.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-utils)
-
-(defvar guix-messages
-  `((package
-     (id
-      ,(lambda (_ entries ids)
-         (guix-message-packages-by-id entries 'package ids)))
-     (name
-      ,(lambda (_ entries names)
-         (guix-message-packages-by-name entries 'package names)))
-     (license
-      ,(lambda (_ entries licenses)
-         (apply #'guix-message-packages-by-license
-                entries 'package licenses)))
-     (location
-      ,(lambda (_ entries locations)
-         (apply #'guix-message-packages-by-location
-                entries 'package locations)))
-     (from-file
-      (0 "No package in file '%s'." val)
-      (1 "Package from file '%s'." val))
-     (regexp
-      (0 "No packages matching '%s'." val)
-      (1 "A single package matching '%s'." val)
-      (many "%d packages matching '%s'." count val))
-     (all-available
-      (0 "No packages are available for some reason.")
-      (1 "A single available package (that's strange).")
-      (many "%d available packages." count))
-     (newest-available
-      (0 "No packages are available for some reason.")
-      (1 "A single newest available package (that's strange).")
-      (many "%d newest available packages." count))
-     (installed
-      (0 "No packages installed in profile '%s'." profile)
-      (1 "A single package installed in profile '%s'." profile)
-      (many "%d packages installed in profile '%s'." count profile))
-     (obsolete
-      (0 "No obsolete packages in profile '%s'." profile)
-      (1 "A single obsolete package in profile '%s'." profile)
-      (many "%d obsolete packages in profile '%s'." count profile)))
-
-    (output
-     (id
-      ,(lambda (_ entries ids)
-         (guix-message-packages-by-id entries 'output ids)))
-     (name
-      ,(lambda (_ entries names)
-         (guix-message-packages-by-name entries 'output names)))
-     (license
-      ,(lambda (_ entries licenses)
-         (apply #'guix-message-packages-by-license
-                entries 'output licenses)))
-     (location
-      ,(lambda (_ entries locations)
-         (apply #'guix-message-packages-by-location
-                entries 'output locations)))
-     (from-file
-      (0 "No package in file '%s'." val)
-      (1 "Package from file '%s'." val)
-      (many "Package outputs from file '%s'." val))
-     (regexp
-      (0 "No package outputs matching '%s'." val)
-      (1 "A single package output matching '%s'." val)
-      (many "%d package outputs matching '%s'." count val))
-     (all-available
-      (0 "No package outputs are available for some reason.")
-      (1 "A single available package output (that's strange).")
-      (many "%d available package outputs." count))
-     (newest-available
-      (0 "No package outputs are available for some reason.")
-      (1 "A single newest available package output (that's strange).")
-      (many "%d newest available package outputs." count))
-     (installed
-      (0 "No package outputs installed in profile '%s'." profile)
-      (1 "A single package output installed in profile '%s'." profile)
-      (many "%d package outputs installed in profile '%s'." count profile))
-     (obsolete
-      (0 "No obsolete package outputs in profile '%s'." profile)
-      (1 "A single obsolete package output in profile '%s'." profile)
-      (many "%d obsolete package outputs in profile '%s'." count profile))
-     (profile-diff
-      guix-message-outputs-by-diff))
-
-    (generation
-     (id
-      (0 "Generations not found.")
-      (1 "")
-      (many "%d generations." count))
-     (last
-      (0 "No generations in profile '%s'." profile)
-      (1 "The last generation of profile '%s'." profile)
-      (many "%d last generations of profile '%s'." count profile))
-     (all
-      (0 "No generations in profile '%s'." profile)
-      (1 "A single generation available in profile '%s'." profile)
-      (many "%d generations available in profile '%s'." count profile))
-     (time
-      guix-message-generations-by-time))))
-
-(defun guix-message-string-name (name)
-  "Return a quoted name string."
-  (concat "'" name "'"))
-
-(defun guix-message-string-entry-type (entry-type &optional plural)
-  "Return a string denoting an ENTRY-TYPE."
-  (cl-ecase entry-type
-    (package
-     (if plural "packages" "package"))
-    (output
-     (if plural "package outputs" "package output"))
-    (generation
-     (if plural "generations" "generation"))))
-
-(defun guix-message-string-entries (count entry-type)
-  "Return a string denoting the COUNT of ENTRY-TYPE entries."
-  (cl-case count
-    (0 (concat "No "
-               (guix-message-string-entry-type
-                entry-type 'plural)))
-    (1 (concat "A single "
-               (guix-message-string-entry-type
-                entry-type)))
-    (t (format "%d %s"
-               count
-               (guix-message-string-entry-type
-                entry-type 'plural)))))
-
-(defun guix-message-packages-by-id (entries entry-type ids)
-  "Display a message for packages or outputs searched by IDS."
-  (let* ((count (length entries))
-         (str-beg (guix-message-string-entries count entry-type))
-         (str-end (if (> count 1)
-                      (concat "with the following IDs: "
-                              (mapconcat #'guix-get-string ids ", "))
-                    (concat "with ID " (guix-get-string (car ids))))))
-    (if (zerop count)
-        (message "%s %s.
-Most likely, Guix REPL was restarted, so IDs are not actual
-anymore, because they live only during the REPL process.
-Try \"M-x guix-search-by-name\"."
-                 str-beg str-end)
-      (message "%s %s." str-beg str-end))))
-
-(defun guix-message-packages-by-name (entries entry-type names)
-  "Display a message for packages or outputs searched by NAMES."
-  (let* ((count (length entries))
-         (str-beg (guix-message-string-entries count entry-type))
-         (str-end (if (cdr names)
-                      (concat "matching the following names: "
-                              (mapconcat #'guix-message-string-name
-                                         names ", "))
-                    (concat "with name "
-                            (guix-message-string-name (car names))))))
-    (message "%s %s." str-beg str-end)))
-
-(defun guix-message-packages-by-license (entries entry-type license)
-  "Display a message for packages or outputs searched by LICENSE."
-  (let* ((count (length entries))
-         (str-beg (guix-message-string-entries count entry-type))
-         (str-end (format "with license '%s'" license)))
-    (message "%s %s." str-beg str-end)))
-
-(defun guix-message-packages-by-location (entries entry-type location)
-  "Display a message for packages or outputs searched by LOCATION."
-  (let* ((count   (length entries))
-         (str-beg (guix-message-string-entries count entry-type))
-         (str-end (format "placed in '%s'" location)))
-    (message "%s %s." str-beg str-end)))
-
-(defun guix-message-generations-by-time (profile entries times)
-  "Display a message for generations searched by TIMES."
-  (let* ((count (length entries))
-         (str-beg (guix-message-string-entries count 'generation))
-         (time-beg (guix-get-time-string (car  times)))
-         (time-end (guix-get-time-string (cadr times))))
-    (message (concat "%s of profile '%s'\n"
-                     "matching time period '%s' - '%s'.")
-             str-beg profile time-beg time-end)))
-
-(defun guix-message-outputs-by-diff (_ entries profiles)
-  "Display a message for outputs searched by PROFILES difference."
-  (let* ((count (length entries))
-         (str-beg (guix-message-string-entries count 'output))
-         (profile1 (car  profiles))
-         (profile2 (cadr profiles)))
-    (cl-multiple-value-bind (new old str-action)
-        (if (string-lessp profile2 profile1)
-            (list profile1 profile2 "added to")
-          (list profile2 profile1 "removed from"))
-      (message "%s %s profile '%s' comparing with profile '%s'."
-               str-beg str-action new old))))
-
-(defun guix-result-message (profile entries entry-type
-                            search-type search-vals)
-  "Display an appropriate message after displaying ENTRIES."
-  (let* ((type-spec (guix-assq-value guix-messages
-                                     (if (eq entry-type 'system-generation)
-                                         'generation
-                                       entry-type)
-                                     search-type))
-         (fun-or-count-spec (car type-spec)))
-    (if (functionp fun-or-count-spec)
-        (funcall fun-or-count-spec profile entries search-vals)
-      (let* ((count     (length entries))
-             (count-key (if (> count 1) 'many count))
-             (msg-spec  (guix-assq-value type-spec count-key))
-             (msg       (car msg-spec))
-             (args      (cdr msg-spec)))
-        (mapc (lambda (subst)
-                (setq args (cl-substitute (cdr subst) (car subst) args)))
-              `((count   . ,count)
-                (val     . ,(car search-vals))
-                (profile . ,profile)))
-        (apply #'message msg args)))))
-
-(provide 'guix-messages)
-
-;;; guix-messages.el ends here
diff --git a/emacs/guix-pcomplete.el b/emacs/guix-pcomplete.el
deleted file mode 100644
index 785e54e..0000000
--- a/emacs/guix-pcomplete.el
+++ /dev/null
@@ -1,370 +0,0 @@
-;;; guix-pcomplete.el --- Functions for completing guix commands  -*- lexical-binding: t -*-
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides completions for "guix" command that may be used in
-;; `shell', `eshell' and wherever `pcomplete' works.
-
-;;; Code:
-
-(require 'pcomplete)
-(require 'pcmpl-unix)
-(require 'cl-lib)
-(require 'guix-utils)
-(require 'guix-help-vars)
-
-\f
-;;; Interacting with guix
-
-(defcustom guix-pcomplete-guix-program (executable-find "guix")
-  "Name of the 'guix' program.
-It is used to find guix commands, options, packages, etc."
-  :type 'file
-  :group 'pcomplete
-  :group 'guix)
-
-(defun guix-pcomplete-run-guix (&rest args)
-  "Run `guix-pcomplete-guix-program' with ARGS.
-Insert the output to the current buffer."
-  (apply #'call-process
-         guix-pcomplete-guix-program nil t nil args))
-
-(defun guix-pcomplete-run-guix-and-search (regexp &optional group
-                                                  &rest args)
-  "Run `guix-pcomplete-guix-program' with ARGS and search for matches.
-Return a list of strings matching REGEXP.
-GROUP specifies a parenthesized expression used in REGEXP."
-  (with-temp-buffer
-    (apply #'guix-pcomplete-run-guix args)
-    (let (result)
-      (guix-while-search regexp
-        (push (match-string-no-properties group) result))
-      (nreverse result))))
-
-(defmacro guix-pcomplete-define-options-finder (name docstring regexp
-                                                     &optional filter)
-  "Define function NAME to receive guix options and commands.
-
-The defined function takes an optional COMMAND argument.  This
-function will run 'guix COMMAND --help' (or 'guix --help' if
-COMMAND is nil) using `guix-pcomplete-run-guix-and-search' and
-return its result.
-
-If FILTER is specified, it should be a function.  The result is
-passed to this FILTER as argument and the result value of this
-function call is returned."
-  (declare (doc-string 2) (indent 1))
-  `(guix-memoized-defun ,name (&optional command)
-     ,docstring
-     (let* ((args '("--help"))
-            (args (if command (cons command args) args))
-            (res (apply #'guix-pcomplete-run-guix-and-search
-                        ,regexp guix-help-parse-regexp-group args)))
-       ,(if filter
-            `(funcall ,filter res)
-          'res))))
-
-(guix-pcomplete-define-options-finder guix-pcomplete-commands
-  "If COMMAND is nil, return a list of available guix commands.
-If COMMAND is non-nil (it should be a string), return available
-subcommands, actions, etc. for this guix COMMAND."
-  guix-help-parse-command-regexp)
-
-(guix-pcomplete-define-options-finder guix-pcomplete-long-options
-  "Return a list of available long options for guix COMMAND."
-  guix-help-parse-long-option-regexp)
-
-(guix-pcomplete-define-options-finder guix-pcomplete-short-options
-  "Return a string with available short options for guix COMMAND."
-  guix-help-parse-short-option-regexp
-  (lambda (list)
-    (guix-concat-strings list "")))
-
-(guix-memoized-defun guix-pcomplete-all-packages ()
-  "Return a list of all available Guix packages."
-  (guix-pcomplete-run-guix-and-search
-   guix-help-parse-package-regexp
-   guix-help-parse-regexp-group
-   "package" "--list-available"))
-
-(guix-memoized-defun guix-pcomplete-installed-packages (&optional profile)
-  "Return a list of Guix packages installed in PROFILE."
-  (let* ((args (and profile
-                    (list (concat "--profile=" profile))))
-         (args (append '("package" "--list-installed") args)))
-    (apply #'guix-pcomplete-run-guix-and-search
-           guix-help-parse-package-regexp
-           guix-help-parse-regexp-group
-           args)))
-
-(guix-memoized-defun guix-pcomplete-lint-checkers ()
-  "Return a list of all available lint checkers."
-  (guix-pcomplete-run-guix-and-search
-   guix-help-parse-list-regexp
-   guix-help-parse-regexp-group
-   "lint" "--list-checkers"))
-
-(guix-memoized-defun guix-pcomplete-graph-types ()
-  "Return a list of all available graph types."
-  (guix-pcomplete-run-guix-and-search
-   guix-help-parse-list-regexp
-   guix-help-parse-regexp-group
-   "graph" "--list-types"))
-
-(guix-memoized-defun guix-pcomplete-refresh-updaters ()
-  "Return a list of all available refresh updater types."
-  (guix-pcomplete-run-guix-and-search
-   guix-help-parse-list-regexp
-   guix-help-parse-regexp-group
-   "refresh" "--list-updaters"))
-
-\f
-;;; Completing
-
-(defvar guix-pcomplete-option-regexp (rx string-start "-")
-  "Regexp to match an option.")
-
-(defvar guix-pcomplete-long-option-regexp (rx string-start "--")
-  "Regexp to match a long option.")
-
-(defvar guix-pcomplete-long-option-with-arg-regexp
-  (rx string-start
-      (group "--" (one-or-more any)) "="
-      (group (zero-or-more any)))
-  "Regexp to match a long option with its argument.
-The first parenthesized group defines the option and the second
-group - the argument.")
-
-(defvar guix-pcomplete-short-option-with-arg-regexp
-  (rx string-start
-      (group "-" (not (any "-")))
-      (group (zero-or-more any)))
-  "Regexp to match a short option with its argument.
-The first parenthesized group defines the option and the second
-group - the argument.")
-
-(defun guix-pcomplete-match-option ()
-  "Return non-nil, if the current argument is an option."
-  (pcomplete-match guix-pcomplete-option-regexp 0))
-
-(defun guix-pcomplete-match-long-option ()
-  "Return non-nil, if the current argument is a long option."
-  (pcomplete-match guix-pcomplete-long-option-regexp 0))
-
-(defun guix-pcomplete-match-long-option-with-arg ()
-  "Return non-nil, if the current argument is a long option with value."
-  (pcomplete-match guix-pcomplete-long-option-with-arg-regexp 0))
-
-(defun guix-pcomplete-match-short-option-with-arg ()
-  "Return non-nil, if the current argument is a short option with value."
-  (pcomplete-match guix-pcomplete-short-option-with-arg-regexp 0))
-
-(defun guix-pcomplete-long-option-arg (option args)
-  "Return a long OPTION's argument from a list of arguments ARGS."
-  (let* ((re (concat "\\`" option "=\\(.*\\)"))
-         (args (cl-member-if (lambda (arg)
-                               (string-match re arg))
-                             args))
-         (cur (car args)))
-    (when cur
-      (match-string-no-properties 1 cur))))
-
-(defun guix-pcomplete-short-option-arg (option args)
-  "Return a short OPTION's argument from a list of arguments ARGS."
-  (let* ((re (concat "\\`" option "\\(.*\\)"))
-         (args (cl-member-if (lambda (arg)
-                               (string-match re arg))
-                             args))
-         (cur (car args)))
-    (when cur
-      (let ((arg (match-string-no-properties 1 cur)))
-        (if (string= "" arg)
-            (cadr args)                 ; take the next arg
-          arg)))))
-
-(defun guix-pcomplete-complete-comma-args (entries)
-  "Complete comma separated arguments using ENTRIES."
-  (let ((index pcomplete-index))
-    (while (= index pcomplete-index)
-      (let* ((args (if (or (guix-pcomplete-match-long-option-with-arg)
-                           (guix-pcomplete-match-short-option-with-arg))
-                       (pcomplete-match-string 2 0)
-                     (pcomplete-arg 0)))
-             (input (if (string-match ".*,\\(.*\\)" args)
-                        (match-string-no-properties 1 args)
-                      args)))
-        (pcomplete-here* entries input)))))
-
-(defun guix-pcomplete-complete-command-arg (command)
-  "Complete argument for guix COMMAND."
-  (cond
-   ((member command
-            '("archive" "build" "challenge" "edit" "environment"
-              "graph" "lint" "refresh" "size"))
-    (while t
-      (pcomplete-here (guix-pcomplete-all-packages))))
-   (t (pcomplete-here* (pcomplete-entries)))))
-
-(defun guix-pcomplete-complete-option-arg (command option &optional input)
-  "Complete argument for COMMAND's OPTION.
-INPUT is the current partially completed string."
-  (cl-flet ((option? (short long)
-              (or (string= option short)
-                  (string= option long)))
-            (command? (&rest commands)
-              (member command commands))
-            (complete (entries)
-              (pcomplete-here entries input nil t))
-            (complete* (entries)
-              (pcomplete-here* entries input t)))
-    (cond
-     ((option? "-L" "--load-path")
-      (complete* (pcomplete-dirs)))
-     ((string= "--key-download" option)
-      (complete* guix-help-key-policies))
-
-     ((command? "package")
-      (cond
-       ;; For '--install[=]' and '--remove[=]', try to complete a package
-       ;; name (INPUT) after the "=" sign, and then the rest packages
-       ;; separated with spaces.
-       ((option? "-i" "--install")
-        (complete (guix-pcomplete-all-packages))
-        (while (not (guix-pcomplete-match-option))
-          (pcomplete-here (guix-pcomplete-all-packages))))
-       ((option? "-r" "--remove")
-        (let* ((profile (or (guix-pcomplete-short-option-arg
-                             "-p" pcomplete-args)
-                            (guix-pcomplete-long-option-arg
-                             "--profile" pcomplete-args)))
-               (profile (and profile (expand-file-name profile))))
-          (complete (guix-pcomplete-installed-packages profile))
-          (while (not (guix-pcomplete-match-option))
-            (pcomplete-here (guix-pcomplete-installed-packages profile)))))
-       ((string= "--show" option)
-        (complete (guix-pcomplete-all-packages)))
-       ((option? "-p" "--profile")
-        (complete* (pcomplete-dirs)))
-       ((or (option? "-f" "--install-from-file")
-            (option? "-m" "--manifest"))
-        (complete* (pcomplete-entries)))))
-
-     ((and (command? "archive" "build" "size")
-           (option? "-s" "--system"))
-      (complete* guix-help-system-types))
-
-     ((and (command? "build")
-           (or (option? "-f" "--file")
-               (option? "-r" "--root")
-               (string= "--with-source" option)))
-      (complete* (pcomplete-entries)))
-
-     ((and (command? "graph")
-           (option? "-t" "--type"))
-      (complete* (guix-pcomplete-graph-types)))
-
-     ((and (command? "environment")
-           (option? "-l" "--load"))
-      (complete* (pcomplete-entries)))
-
-     ((and (command? "hash" "download")
-           (option? "-f" "--format"))
-      (complete* guix-help-hash-formats))
-
-     ((and (command? "lint")
-           (option? "-c" "--checkers"))
-      (guix-pcomplete-complete-comma-args
-       (guix-pcomplete-lint-checkers)))
-
-     ((and (command? "publish")
-           (option? "-u" "--user"))
-      (complete* (pcmpl-unix-user-names)))
-
-     ((command? "refresh")
-      (cond
-       ((option? "-s" "--select")
-        (complete* guix-help-refresh-subsets))
-       ((option? "-t" "--type")
-        (guix-pcomplete-complete-comma-args
-         (guix-pcomplete-refresh-updaters)))))
-
-     ((and (command? "size")
-           (option? "-m" "--map-file"))
-      (complete* (pcomplete-entries))))))
-
-(defun guix-pcomplete-complete-options (command)
-  "Complete options (with their arguments) for guix COMMAND."
-  (while (guix-pcomplete-match-option)
-    (let ((index pcomplete-index))
-      (if (guix-pcomplete-match-long-option)
-
-          ;; Long options.
-          (if (guix-pcomplete-match-long-option-with-arg)
-              (let ((option (pcomplete-match-string 1 0))
-                    (arg    (pcomplete-match-string 2 0)))
-                (guix-pcomplete-complete-option-arg
-                 command option arg))
-
-            (pcomplete-here* (guix-pcomplete-long-options command))
-            ;; We support '--opt arg' style (along with '--opt=arg'),
-            ;; because 'guix package --install/--remove' may be used this
-            ;; way.  So try to complete an argument after the option has
-            ;; been completed.
-            (unless (guix-pcomplete-match-option)
-              (guix-pcomplete-complete-option-arg
-               command (pcomplete-arg 0 -1))))
-
-        ;; Short options.
-        (let ((arg (pcomplete-arg 0)))
-          (if (> (length arg) 2)
-              ;; Support specifying an argument after a short option without
-              ;; spaces (for example, '-L/tmp/foo').
-              (guix-pcomplete-complete-option-arg
-               command
-               (substring-no-properties arg 0 2)
-               (substring-no-properties arg 2))
-            (pcomplete-opt (guix-pcomplete-short-options command))
-            (guix-pcomplete-complete-option-arg
-             command (pcomplete-arg 0 -1)))))
-
-      ;; If there were no completions, move to the next argument and get
-      ;; out if the last argument is achieved.
-      (when (= index pcomplete-index)
-        (if (= pcomplete-index pcomplete-last)
-            (throw 'pcompleted nil)
-          (pcomplete-next-arg))))))
-
-;;;###autoload
-(defun pcomplete/guix ()
-  "Completion for `guix'."
-  (let ((commands (guix-pcomplete-commands)))
-    (pcomplete-here* (cons "--help" commands))
-    (let ((command (pcomplete-arg 'first 1)))
-      (when (member command commands)
-        (guix-pcomplete-complete-options command)
-        (let ((subcommands (guix-pcomplete-commands command)))
-          (when subcommands
-            (pcomplete-here* subcommands)))
-        (guix-pcomplete-complete-options command)
-        (guix-pcomplete-complete-command-arg command)))))
-
-(provide 'guix-pcomplete)
-
-;;; guix-pcomplete.el ends here
diff --git a/emacs/guix-popup.el b/emacs/guix-popup.el
deleted file mode 100644
index 59e98a3..0000000
--- a/emacs/guix-popup.el
+++ /dev/null
@@ -1,48 +0,0 @@
-;;; guix-popup.el --- Popup windows library
-
-;; Copyright © 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides `guix-define-popup' macro which is just an alias
-;; to `magit-define-popup'.  According to the manual (info
-;; "(magit-popup) Defining prefix and suffix commands") `magit-popup'
-;; library will eventually be superseded by a more general library.
-
-;;; Code:
-
-(require 'magit-popup)
-
-(defalias 'guix-define-popup 'magit-define-popup)
-
-(defvar guix-popup-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "("
-            (group "guix-define-popup")
-            symbol-end
-            (zero-or-more blank)
-            (zero-or-one
-             (group (one-or-more (or (syntax word) (syntax symbol))))))
-       (1 font-lock-keyword-face)
-       (2 font-lock-function-name-face nil t)))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-popup-font-lock-keywords)
-
-(provide 'guix-popup)
-
-;;; guix-popup.el ends here
diff --git a/emacs/guix-prettify.el b/emacs/guix-prettify.el
deleted file mode 100644
index 38d72e8..0000000
--- a/emacs/guix-prettify.el
+++ /dev/null
@@ -1,210 +0,0 @@
-;;; guix-prettify.el --- Prettify Guix store file names
-
-;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This package provides minor-mode for prettifying Guix store file
-;; names — i.e., after enabling `guix-prettify-mode',
-;; '/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' names will be
-;; replaced with '/gnu/store/…-foo-0.1' in the current buffer.  There is
-;; also `global-guix-prettify-mode' for global prettifying.
-
-;; To install, add the following to your emacs init file:
-;;
-;;   (add-to-list 'load-path "/path/to/dir-with-guix-prettify")
-;;   (autoload 'guix-prettify-mode "guix-prettify" nil t)
-;;   (autoload 'global-guix-prettify-mode "guix-prettify" nil t)
-
-;; If you want to enable/disable composition after "M-x font-lock-mode",
-;; use the following setting:
-;;
-;;   (setq font-lock-extra-managed-props
-;;         (cons 'composition font-lock-extra-managed-props))
-
-;; Credits:
-;;
-;; Thanks to Ludovic Courtès for the idea of this package.
-;;
-;; Thanks to the authors of `prettify-symbols-mode' (part of Emacs 24.4)
-;; and "pretty-symbols.el" <http://github.com/drothlis/pretty-symbols>
-;; for the code.  It helped to write this package.
-
-;;; Code:
-
-(require 'guix-utils)
-
-(defgroup guix-prettify nil
-  "Prettify Guix store file names."
-  :prefix "guix-prettify-"
-  :group 'guix
-  :group 'font-lock
-  :group 'convenience)
-
-(defcustom guix-prettify-char ?…
-  "Character used for prettifying."
-  :type 'character
-  :group 'guix-prettify)
-
-(defcustom guix-prettify-decompose-force nil
-  "If non-nil, remove any composition.
-
-By default, after disabling `guix-prettify-mode',
-compositions (prettifying names with `guix-prettify-char') are
-removed only from strings matching `guix-prettify-regexp', so
-that compositions created by other modes are left untouched.
-
-Set this variable to non-nil, if you want to remove any
-composition unconditionally (like `prettify-symbols-mode' does).
-Most likely it will do no harm and will make the process of
-disabling `guix-prettify-mode' a little faster."
-  :type 'boolean
-  :group 'guix-prettify)
-
-(defcustom guix-prettify-regexp
-  ;; The following file names / URLs should be abbreviated:
-
-  ;; /gnu/store/…-foo-0.1
-  ;; /nix/store/…-foo-0.1
-  ;; http://hydra.gnu.org/nar/…-foo-0.1
-  ;; http://hydra.gnu.org/log/…-foo-0.1
-
-  (rx "/" (or "store" "nar" "log") "/"
-      ;; Hash-parts do not include "e", "o", "u" and "t".  See base32Chars
-      ;; at <https://github.com/NixOS/nix/blob/master/src/libutil/hash.cc>
-      (group (= 32 (any "0-9" "a-d" "f-n" "p-s" "v-z"))))
-  "Regexp matching file names for prettifying.
-
-Disable `guix-prettify-mode' before modifying this variable and
-make sure to modify `guix-prettify-regexp-group' if needed.
-
-Example of a \"deeper\" prettifying:
-
-  (setq guix-prettify-regexp \"store/[[:alnum:]]\\\\\\={32\\\\}\"
-        guix-prettify-regexp-group 0)
-
-This will transform
-'/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' into
-'/gnu/…-foo-0.1'"
-  :type 'regexp
-  :group 'guix-prettify)
-
-(defcustom guix-prettify-regexp-group 1
-  "Regexp group in `guix-prettify-regexp' for prettifying."
-  :type 'integer
-  :group 'guix-prettify)
-
-(defvar guix-prettify-special-modes
-  '(guix-info-mode ibuffer-mode)
-  "List of special modes that support font-locking.
-
-By default, \\[global-guix-prettify-mode] enables prettifying in
-all buffers except the ones where `font-lock-defaults' is
-nil (see Info node `(elisp) Font Lock Basics'), because it may
-break the existing highlighting.
-
-Modes from this list and all derived modes are exceptions
-\(`global-guix-prettify-mode' enables prettifying there).")
-
-(defvar guix-prettify-flush-function
-  (cond ((fboundp 'font-lock-flush) #'font-lock-flush)
-        ((fboundp 'jit-lock-refontify) #'jit-lock-refontify))
-  "Function used to refontify buffer.
-This function is called without arguments after
-enabling/disabling `guix-prettify-mode'.  If nil, do nothing.")
-
-(defun guix-prettify-compose ()
-  "Compose matching region in the current buffer."
-  (let ((beg (match-beginning guix-prettify-regexp-group))
-        (end (match-end       guix-prettify-regexp-group)))
-    (compose-region beg end guix-prettify-char 'decompose-region))
-  ;; Return nil because we're not adding any face property.
-  nil)
-
-(defun guix-prettify-decompose-buffer ()
-  "Remove file names compositions from the current buffer."
-  (with-silent-modifications
-    (let ((inhibit-read-only t))
-      (if guix-prettify-decompose-force
-          (remove-text-properties (point-min)
-                                  (point-max)
-                                  '(composition nil))
-        (guix-while-search guix-prettify-regexp
-          (remove-text-properties
-           (match-beginning guix-prettify-regexp-group)
-           (match-end       guix-prettify-regexp-group)
-           '(composition nil)))))))
-
-;;;###autoload
-(define-minor-mode guix-prettify-mode
-  "Toggle Guix Prettify mode.
-
-With a prefix argument ARG, enable Guix Prettify mode if ARG is
-positive, and disable it otherwise.  If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-When Guix Prettify mode is enabled, hash-parts of the Guix store
-file names (see `guix-prettify-regexp') are prettified,
-i.e. displayed as `guix-prettify-char' character.  This mode can
-be enabled programmatically using hooks:
-
-  (add-hook 'shell-mode-hook 'guix-prettify-mode)
-
-It is possible to enable the mode in any buffer, however not any
-buffer's highlighting may survive after adding new elements to
-`font-lock-keywords' (see `guix-prettify-special-modes' for
-details).
-
-Also you can use `global-guix-prettify-mode' to enable Guix
-Prettify mode for all modes that support font-locking."
-  :init-value nil
-  :lighter " …"
-  (let ((keywords `((,guix-prettify-regexp
-                     (,guix-prettify-regexp-group
-                      (guix-prettify-compose))))))
-    (if guix-prettify-mode
-        ;; Turn on.
-        (font-lock-add-keywords nil keywords)
-      ;; Turn off.
-      (font-lock-remove-keywords nil keywords)
-      (guix-prettify-decompose-buffer))
-    (and guix-prettify-flush-function
-         (funcall guix-prettify-flush-function))))
-
-(defun guix-prettify-supported-p ()
-  "Return non-nil, if the mode can be harmlessly enabled in current buffer."
-  (or font-lock-defaults
-      (apply #'derived-mode-p guix-prettify-special-modes)))
-
-(defun guix-prettify-turn-on ()
-  "Enable `guix-prettify-mode' in the current buffer if needed.
-See `guix-prettify-special-modes' for details."
-  (and (not guix-prettify-mode)
-       (guix-prettify-supported-p)
-       (guix-prettify-mode)))
-
-;;;###autoload
-(define-globalized-minor-mode global-guix-prettify-mode
-  guix-prettify-mode guix-prettify-turn-on)
-
-;;;###autoload
-(defalias 'guix-prettify-global-mode 'global-guix-prettify-mode)
-
-(provide 'guix-prettify)
-
-;;; guix-prettify.el ends here
diff --git a/emacs/guix-profiles.el b/emacs/guix-profiles.el
deleted file mode 100644
index 12cf46d..0000000
--- a/emacs/guix-profiles.el
+++ /dev/null
@@ -1,77 +0,0 @@
-;;; guix-profiles.el --- Guix profiles
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-;; Copyright © 2015 Mathieu Lirzin <mthl@openmailbox.org>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(require 'guix-config)
-
-(defvar guix-user-profile
-  (expand-file-name "~/.guix-profile")
-  "User profile.")
-
-(defvar guix-system-profile
-  (concat guix-config-state-directory "/profiles/system")
-  "System profile.")
-
-(defvar guix-default-profile
-  (concat guix-config-state-directory
-          "/profiles/per-user/"
-          (getenv "USER")
-          "/guix-profile")
-  "Default Guix profile.")
-
-(defvar guix-current-profile guix-default-profile
-  "Current profile.")
-
-(defvar guix-system-profile-regexp
-  (concat "\\`" (regexp-quote guix-system-profile))
-  "Regexp matching system profiles.")
-
-(defun guix-system-profile? (profile)
-  "Return non-nil, if PROFILE is a system one."
-  (string-match-p guix-system-profile-regexp profile))
-
-(defun guix-profile-prompt (&optional default)
-  "Prompt for profile and return it.
-Use DEFAULT as a start directory.  If it is nil, use
-`guix-current-profile'."
-  (let* ((path (read-file-name "Profile: "
-                               (file-name-directory
-                                (or default guix-current-profile))))
-         (path (directory-file-name (expand-file-name path))))
-    (if (string= path guix-user-profile)
-        guix-default-profile
-      path)))
-
-(defun guix-set-current-profile (path)
-  "Set `guix-current-profile' to PATH.
-Interactively, prompt for PATH.  With prefix, use
-`guix-default-profile'."
-  (interactive
-   (list (if current-prefix-arg
-             guix-default-profile
-           (guix-profile-prompt))))
-  (setq guix-current-profile path)
-  (message "Current profile has been set to '%s'."
-           guix-current-profile))
-
-(provide 'guix-profiles)
-
-;;; guix-profiles.el ends here
diff --git a/emacs/guix-read.el b/emacs/guix-read.el
deleted file mode 100644
index 5423c9b..0000000
--- a/emacs/guix-read.el
+++ /dev/null
@@ -1,147 +0,0 @@
-;;; guix-read.el --- Minibuffer readers
-
-;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides functions to prompt a user for packages, system
-;; types, hash formats and other guix related stuff.
-
-;;; Code:
-
-(require 'guix-help-vars)
-(require 'guix-utils)
-(require 'guix-backend)
-(require 'guix-guile)
-
-\f
-;;; Receivable lists of packages, lint checkers, etc.
-
-(guix-memoized-defun guix-graph-type-names ()
-  "Return a list of names of available graph node types."
-  (guix-eval-read (guix-make-guile-expression 'graph-type-names)))
-
-(guix-memoized-defun guix-refresh-updater-names ()
-  "Return a list of names of available refresh updater types."
-  (guix-eval-read (guix-make-guile-expression 'refresh-updater-names)))
-
-(guix-memoized-defun guix-lint-checker-names ()
-  "Return a list of names of available lint checkers."
-  (guix-eval-read (guix-make-guile-expression 'lint-checker-names)))
-
-(guix-memoized-defun guix-package-names ()
-  "Return a list of names of available packages."
-  (sort
-   ;; Work around <https://github.com/jaor/geiser/issues/64>:
-   ;; list of strings is parsed much slower than list of lists,
-   ;; so we use 'package-names-lists' instead of 'package-names'.
-
-   ;; (guix-eval-read (guix-make-guile-expression 'package-names))
-
-   (mapcar #'car
-           (guix-eval-read (guix-make-guile-expression
-                            'package-names-lists)))
-   #'string<))
-
-(guix-memoized-defun guix-license-names ()
-  "Return a list of names of available licenses."
-  (guix-eval-read (guix-make-guile-expression 'license-names)))
-
-(guix-memoized-defun guix-package-locations ()
-  "Return a list of available package locations."
-  (sort (guix-eval-read (guix-make-guile-expression
-                         'package-location-files))
-        #'string<))
-
-\f
-;;; Readers
-
-(guix-define-readers
- :completions-var guix-help-system-types
- :single-reader guix-read-system-type
- :single-prompt "System type: ")
-
-(guix-define-readers
- :completions-var guix-help-source-types
- :single-reader guix-read-source-type
- :single-prompt "Source type: ")
-
-(guix-define-readers
- :completions-var guix-help-hash-formats
- :single-reader guix-read-hash-format
- :single-prompt "Hash format: ")
-
-(guix-define-readers
- :completions-var guix-help-refresh-subsets
- :single-reader guix-read-refresh-subset
- :single-prompt "Refresh subset: ")
-
-(guix-define-readers
- :completions-getter guix-refresh-updater-names
- :multiple-reader guix-read-refresh-updater-names
- :multiple-prompt "Refresh updater,s: "
- :multiple-separator ",")
-
-(guix-define-readers
- :completions-var guix-help-key-policies
- :single-reader guix-read-key-policy
- :single-prompt "Key policy: ")
-
-(guix-define-readers
- :completions-var guix-help-elpa-archives
- :single-reader guix-read-elpa-archive
- :single-prompt "ELPA archive: ")
-
-(guix-define-readers
- :completions-var guix-help-verify-options
- :multiple-reader guix-read-verify-options
- :multiple-prompt "Verify option,s: "
- :multiple-separator ",")
-
-(guix-define-readers
- :completions-getter guix-graph-type-names
- :single-reader guix-read-graph-type
- :single-prompt "Graph node type: ")
-
-(guix-define-readers
- :completions-getter guix-lint-checker-names
- :multiple-reader guix-read-lint-checker-names
- :multiple-prompt "Linter,s: "
- :multiple-separator ",")
-
-(guix-define-readers
- :completions-getter guix-package-names
- :single-reader guix-read-package-name
- :single-prompt "Package: "
- :multiple-reader guix-read-package-names
- :multiple-prompt "Package,s: "
- :multiple-separator " ")
-
-(guix-define-readers
- :completions-getter guix-license-names
- :single-reader guix-read-license-name
- :single-prompt "License: ")
-
-(guix-define-readers
- :completions-getter guix-package-locations
- :single-reader guix-read-package-location
- :single-prompt "Location: ")
-
-(provide 'guix-read)
-
-;;; guix-read.el ends here
diff --git a/emacs/guix-ui-generation.el b/emacs/guix-ui-generation.el
deleted file mode 100644
index 67cf629..0000000
--- a/emacs/guix-ui-generation.el
+++ /dev/null
@@ -1,456 +0,0 @@
-;;; guix-ui-generation.el --- Interface for displaying generations  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides an interface for displaying profile generations in
-;; 'list' and 'info' buffers, and commands for working with them.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-buffer)
-(require 'guix-list)
-(require 'guix-info)
-(require 'guix-ui)
-(require 'guix-ui-package)
-(require 'guix-base)
-(require 'guix-backend)
-(require 'guix-guile)
-(require 'guix-entry)
-(require 'guix-utils)
-(require 'guix-profiles)
-
-(guix-ui-define-entry-type generation)
-
-(defun guix-generation-get-display (profile search-type &rest search-values)
-  "Search for generations and show results.
-
-If PROFILE is nil, use `guix-current-profile'.
-
-See `guix-ui-get-entries' for the meaning of SEARCH-TYPE and
-SEARCH-VALUES."
-  (apply #'guix-list-get-display-entries
-         'generation
-         (or profile guix-current-profile)
-         search-type search-values))
-
-(defun guix-delete-generations (profile generations
-                                &optional operation-buffer)
-  "Delete GENERATIONS from PROFILE.
-Each element from GENERATIONS is a generation number."
-  (when (or (not guix-operation-confirm)
-            (y-or-n-p
-             (let ((count (length generations)))
-               (if (> count 1)
-                   (format "Delete %d generations from profile '%s'? "
-                           count profile)
-                 (format "Delete generation %d from profile '%s'? "
-                         (car generations) profile)))))
-    (guix-eval-in-repl
-     (guix-make-guile-expression
-      'delete-generations* profile generations)
-     operation-buffer)))
-
-(defun guix-switch-to-generation (profile generation
-                                  &optional operation-buffer)
-  "Switch PROFILE to GENERATION."
-  (when (or (not guix-operation-confirm)
-            (y-or-n-p (format "Switch profile '%s' to generation %d? "
-                              profile generation)))
-    (guix-eval-in-repl
-     (guix-make-guile-expression
-      'switch-to-generation* profile generation)
-     operation-buffer)))
-
-(defun guix-system-generation? ()
-  "Return non-nil, if current generation is a system one."
-  (eq (guix-buffer-current-entry-type)
-      'system-generation))
-
-(defun guix-generation-current-packages-profile (&optional generation)
-  "Return a directory where packages are installed for the
-current profile's GENERATION."
-  (guix-packages-profile (guix-ui-current-profile)
-                         generation
-                         (guix-system-generation?)))
-
-\f
-;;; Generation 'info'
-
-(guix-ui-info-define-interface generation
-  :buffer-name "*Guix Generation Info*"
-  :format '((number format guix-generation-info-insert-number)
-            (prev-number format (format))
-            (current format guix-generation-info-insert-current)
-            (path simple (indent guix-file))
-            (time format (time)))
-  :titles '((path . "File name")
-            (prev-number . "Previous number")))
-
-(defface guix-generation-info-number
-  '((t :inherit font-lock-keyword-face))
-  "Face used for a number of a generation."
-  :group 'guix-generation-info-faces)
-
-(defface guix-generation-info-current
-  '((t :inherit guix-package-info-installed-outputs))
-  "Face used if a generation is the current one."
-  :group 'guix-generation-info-faces)
-
-(defface guix-generation-info-not-current
-  '((t nil))
-  "Face used if a generation is not the current one."
-  :group 'guix-generation-info-faces)
-
-(defun guix-generation-info-insert-number (number &optional _)
-  "Insert generation NUMBER and action buttons."
-  (guix-info-insert-value-format number 'guix-generation-info-number)
-  (guix-info-insert-indent)
-  (guix-info-insert-action-button
-   "Packages"
-   (lambda (btn)
-     (guix-buffer-get-display-entries
-      'list guix-package-list-type
-      (list (guix-generation-current-packages-profile
-             (button-get btn 'number))
-            'installed)
-      'add))
-   "Show installed packages for this generation"
-   'number number)
-  (guix-info-insert-indent)
-  (guix-info-insert-action-button
-   "Delete"
-   (lambda (btn)
-     (guix-delete-generations (guix-ui-current-profile)
-                              (list (button-get btn 'number))
-                              (current-buffer)))
-   "Delete this generation"
-   'number number))
-
-(defun guix-generation-info-insert-current (val entry)
-  "Insert boolean value VAL showing whether this generation is current."
-  (if val
-      (guix-info-insert-value-format "Yes" 'guix-generation-info-current)
-    (guix-info-insert-value-format "No" 'guix-generation-info-not-current)
-    (guix-info-insert-indent)
-    (guix-info-insert-action-button
-     "Switch"
-     (lambda (btn)
-       (guix-switch-to-generation (guix-ui-current-profile)
-                                  (button-get btn 'number)
-                                  (current-buffer)))
-     "Switch to this generation (make it the current one)"
-     'number (guix-entry-value entry 'number))))
-
-\f
-;;; Generation 'list'
-
-(guix-ui-list-define-interface generation
-  :buffer-name "*Guix Generation List*"
-  :format '((number nil 5 guix-list-sort-numerically-0 :right-align t)
-            (current guix-generation-list-get-current 10 t)
-            (time guix-list-get-time 20 t)
-            (path guix-list-get-file-name 30 t))
-  :titles '((number . "N."))
-  :sort-key '(number . t)
-  :marks '((delete . ?D)))
-
-(let ((map guix-generation-list-mode-map))
-  (define-key map (kbd "RET") 'guix-generation-list-show-packages)
-  (define-key map (kbd "+")   'guix-generation-list-show-added-packages)
-  (define-key map (kbd "-")   'guix-generation-list-show-removed-packages)
-  (define-key map (kbd "=")   'guix-generation-list-diff)
-  (define-key map (kbd "D")   'guix-generation-list-diff)
-  (define-key map (kbd "e")   'guix-generation-list-ediff)
-  (define-key map (kbd "x")   'guix-generation-list-execute)
-  (define-key map (kbd "s")   'guix-generation-list-switch)
-  (define-key map (kbd "c")   'guix-generation-list-switch)
-  (define-key map (kbd "d")   'guix-generation-list-mark-delete))
-
-(defun guix-generation-list-get-current (val &optional _)
-  "Return string from VAL showing whether this generation is current.
-VAL is a boolean value."
-  (if val "(current)" ""))
-
-(defun guix-generation-list-switch ()
-  "Switch current profile to the generation at point."
-  (interactive)
-  (let* ((entry   (guix-list-current-entry))
-         (current (guix-entry-value entry 'current))
-         (number  (guix-entry-value entry 'number)))
-    (if current
-        (user-error "This generation is already the current one")
-      (guix-switch-to-generation (guix-ui-current-profile)
-                                 number (current-buffer)))))
-
-(defun guix-generation-list-show-packages ()
-  "List installed packages for the generation at point."
-  (interactive)
-  (guix-package-get-display
-   (guix-generation-current-packages-profile (guix-list-current-id))
-   'installed))
-
-(defun guix-generation-list-generations-to-compare ()
-  "Return a sorted list of 2 marked generations for comparing."
-  (let ((numbers (guix-list-get-marked-id-list 'general)))
-    (if (/= (length numbers) 2)
-        (user-error "2 generations should be marked for comparing")
-      (sort numbers #'<))))
-
-(defun guix-generation-list-profiles-to-compare ()
-  "Return a sorted list of 2 marked generation profiles for comparing."
-  (mapcar #'guix-generation-current-packages-profile
-          (guix-generation-list-generations-to-compare)))
-
-(defun guix-generation-list-show-added-packages ()
-  "List package outputs added to the latest marked generation.
-If 2 generations are marked with \\[guix-list-mark], display
-outputs installed in the latest marked generation that were not
-installed in the other one."
-  (interactive)
-  (guix-buffer-get-display-entries
-   'list 'output
-   (cl-list* (guix-ui-current-profile)
-             'profile-diff
-             (reverse (guix-generation-list-profiles-to-compare)))
-   'add))
-
-(defun guix-generation-list-show-removed-packages ()
-  "List package outputs removed from the latest marked generation.
-If 2 generations are marked with \\[guix-list-mark], display
-outputs not installed in the latest marked generation that were
-installed in the other one."
-  (interactive)
-  (guix-buffer-get-display-entries
-   'list 'output
-   (cl-list* (guix-ui-current-profile)
-             'profile-diff
-             (guix-generation-list-profiles-to-compare))
-   'add))
-
-(defun guix-generation-list-compare (diff-fun gen-fun)
-  "Run GEN-FUN on the 2 marked generations and run DIFF-FUN on the results."
-  (cl-multiple-value-bind (gen1 gen2)
-      (guix-generation-list-generations-to-compare)
-    (funcall diff-fun
-             (funcall gen-fun gen1)
-             (funcall gen-fun gen2))))
-
-(defun guix-generation-list-ediff-manifests ()
-  "Run Ediff on manifests of the 2 marked generations."
-  (interactive)
-  (guix-generation-list-compare
-   #'ediff-files
-   #'guix-profile-generation-manifest-file))
-
-(defun guix-generation-list-diff-manifests ()
-  "Run Diff on manifests of the 2 marked generations."
-  (interactive)
-  (guix-generation-list-compare
-   #'guix-diff
-   #'guix-profile-generation-manifest-file))
-
-(defun guix-generation-list-ediff-packages ()
-  "Run Ediff on package outputs installed in the 2 marked generations."
-  (interactive)
-  (guix-generation-list-compare
-   #'ediff-buffers
-   #'guix-profile-generation-packages-buffer))
-
-(defun guix-generation-list-diff-packages ()
-  "Run Diff on package outputs installed in the 2 marked generations."
-  (interactive)
-  (guix-generation-list-compare
-   #'guix-diff
-   #'guix-profile-generation-packages-buffer))
-
-(defun guix-generation-list-ediff (arg)
-  "Run Ediff on package outputs installed in the 2 marked generations.
-With ARG, run Ediff on manifests of the marked generations."
-  (interactive "P")
-  (if arg
-      (guix-generation-list-ediff-manifests)
-    (guix-generation-list-ediff-packages)))
-
-(defun guix-generation-list-diff (arg)
-  "Run Diff on package outputs installed in the 2 marked generations.
-With ARG, run Diff on manifests of the marked generations."
-  (interactive "P")
-  (if arg
-      (guix-generation-list-diff-manifests)
-    (guix-generation-list-diff-packages)))
-
-(defun guix-generation-list-mark-delete (&optional arg)
-  "Mark the current generation for deletion and move to the next line.
-With ARG, mark all generations for deletion."
-  (interactive "P")
-  (if arg
-      (guix-list-mark-all 'delete)
-    (guix-list--mark 'delete t)))
-
-(defun guix-generation-list-execute ()
-  "Delete marked generations."
-  (interactive)
-  (let ((marked (guix-list-get-marked-id-list 'delete)))
-    (or marked
-        (user-error "No generations marked for deletion"))
-    (guix-delete-generations (guix-ui-current-profile)
-                             marked (current-buffer))))
-
-\f
-;;; Inserting packages to compare generations
-
-(defcustom guix-generation-packages-buffer-name-function
-  #'guix-generation-packages-buffer-name-default
-  "Function used to define name of a buffer with generation packages.
-This function is called with 2 arguments: PROFILE (string) and
-GENERATION (number)."
-  :type '(choice (function-item guix-generation-packages-buffer-name-default)
-                 (function-item guix-generation-packages-buffer-name-long)
-                 (function :tag "Other function"))
-  :group 'guix-generation)
-
-(defcustom guix-generation-packages-update-buffer t
-  "If non-nil, always update list of packages during comparing generations.
-If nil, generation packages are received only once.  So when you
-compare generation 1 and generation 2, the packages for both
-generations will be received.  Then if you compare generation 1
-and generation 3, only the packages for generation 3 will be
-received.  Thus if you use comparing of different generations a
-lot, you may set this variable to nil to improve the
-performance."
-  :type 'boolean
-  :group 'guix-generation)
-
-(defvar guix-generation-output-name-width 30
-  "Width of an output name \"column\".
-This variable is used in auxiliary buffers for comparing generations.")
-
-(defun guix-generation-packages (profile)
-  "Return a list of sorted packages installed in PROFILE.
-Each element of the list is a list of the package specification
-and its store path."
-  (let ((names+paths (guix-eval-read
-                      (guix-make-guile-expression
-                       'profile->specifications+paths profile))))
-    (sort names+paths
-          (lambda (a b)
-            (string< (car a) (car b))))))
-
-(defun guix-generation-packages-buffer-name-default (profile generation)
-  "Return name of a buffer for displaying GENERATION's package outputs.
-Use base name of PROFILE file name."
-  (let ((profile-name (file-name-base (directory-file-name profile))))
-    (format "*Guix %s: generation %s*"
-            profile-name generation)))
-
-(defun guix-generation-packages-buffer-name-long (profile generation)
-  "Return name of a buffer for displaying GENERATION's package outputs.
-Use the full PROFILE file name."
-  (format "*Guix generation %s (%s)*"
-          generation profile))
-
-(defun guix-generation-packages-buffer-name (profile generation)
-  "Return name of a buffer for displaying GENERATION's package outputs."
-  (funcall guix-generation-packages-buffer-name-function
-           profile generation))
-
-(defun guix-generation-insert-package (name path)
-  "Insert package output NAME and store PATH at point."
-  (insert name)
-  (indent-to guix-generation-output-name-width 2)
-  (insert path "\n"))
-
-(defun guix-generation-insert-packages (buffer profile)
-  "Insert package outputs installed in PROFILE in BUFFER."
-  (with-current-buffer buffer
-    (setq buffer-read-only nil
-          indent-tabs-mode nil)
-    (erase-buffer)
-    (mapc (lambda (name+path)
-            (guix-generation-insert-package
-             (car name+path) (cadr name+path)))
-          (guix-generation-packages profile))))
-
-(defun guix-generation-packages-buffer (profile generation &optional system?)
-  "Return buffer with package outputs installed in PROFILE's GENERATION.
-Create the buffer if needed."
-  (let ((buf-name (guix-generation-packages-buffer-name
-                   profile generation)))
-    (or (and (null guix-generation-packages-update-buffer)
-             (get-buffer buf-name))
-        (let ((buf (get-buffer-create buf-name)))
-          (guix-generation-insert-packages
-           buf
-           (guix-packages-profile profile generation system?))
-          buf))))
-
-(defun guix-profile-generation-manifest-file (generation)
-  "Return the file name of a GENERATION's manifest.
-GENERATION is a generation number of the current profile."
-  (guix-manifest-file (guix-ui-current-profile)
-                      generation
-                      (guix-system-generation?)))
-
-(defun guix-profile-generation-packages-buffer (generation)
-  "Insert GENERATION's package outputs in a buffer and return it.
-GENERATION is a generation number of the current profile."
-  (guix-generation-packages-buffer (guix-ui-current-profile)
-                                   generation
-                                   (guix-system-generation?)))
-
-\f
-;;; Interactive commands
-
-;;;###autoload
-(defun guix-generations (&optional profile)
-  "Display information about all generations.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive (list (guix-ui-read-profile)))
-  (guix-generation-get-display profile 'all))
-
-;;;###autoload
-(defun guix-last-generations (number &optional profile)
-  "Display information about last NUMBER generations.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (read-number "The number of last generations: ")
-         (guix-ui-read-profile)))
-  (guix-generation-get-display profile 'last number))
-
-;;;###autoload
-(defun guix-generations-by-time (from to &optional profile)
-  "Display information about generations created between FROM and TO.
-FROM and TO should be time values.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (guix-read-date "Find generations (from): ")
-         (guix-read-date "Find generations (to): ")
-         (guix-ui-read-profile)))
-  (guix-generation-get-display profile 'time
-                               (float-time from)
-                               (float-time to)))
-
-(provide 'guix-ui-generation)
-
-;;; guix-ui-generation.el ends here
diff --git a/emacs/guix-ui-license.el b/emacs/guix-ui-license.el
deleted file mode 100644
index cf1b5cd..0000000
--- a/emacs/guix-ui-license.el
+++ /dev/null
@@ -1,150 +0,0 @@
-;;; guix-ui-license.el --- Interface for displaying licenses
-
-;; Copyright © 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides 'list'/'info' interface for displaying licenses of
-;; Guix packages.
-
-;;; Code:
-
-(require 'guix-buffer)
-(require 'guix-list)
-(require 'guix-info)
-(require 'guix-backend)
-(require 'guix-guile)
-(require 'guix-license)
-
-(guix-define-entry-type license)
-
-(defun guix-license-get-entries (search-type &rest args)
-  "Receive 'license' entries.
-SEARCH-TYPE may be one of the following symbols: `all', `id', `name'."
-  (guix-eval-read
-   (apply #'guix-make-guile-expression
-          'license-entries search-type args)))
-
-(defun guix-license-get-display (search-type &rest args)
-  "Search for licenses and show results."
-  (apply #'guix-list-get-display-entries
-         'license search-type args))
-
-(defun guix-license-message (entries search-type &rest args)
-  "Display a message after showing license ENTRIES."
-  ;; Some objects in (guix licenses) module are procedures (e.g.,
-  ;; 'non-copyleft' or 'x11-style').  Such licenses cannot be "described".
-  (when (null entries)
-    (if (cdr args)
-        (message "Unknown licenses.")
-      (message "Unknown license."))))
-
-\f
-;;; License 'info'
-
-(guix-info-define-interface license
-  :buffer-name "*Guix License Info*"
-  :get-entries-function 'guix-license-get-entries
-  :message-function 'guix-license-message
-  :format '((name ignore (simple guix-info-heading))
-            ignore
-            guix-license-insert-packages-button
-            (url ignore (simple guix-url))
-            guix-license-insert-comment
-            ignore
-            guix-license-insert-file)
-  :titles '((url . "URL")))
-
-(declare-function guix-packages-by-license "guix-ui-package")
-
-(defun guix-license-insert-packages-button (entry)
-  "Insert button to display packages by license ENTRY."
-  (let ((license (guix-entry-value entry 'name)))
-    (guix-info-insert-action-button
-     "Packages"
-     (lambda (btn)
-       (guix-packages-by-license (button-get btn 'license)))
-     (format "Display packages with license '%s'" license)
-     'license license)))
-
-(defun guix-license-insert-comment (entry)
-  "Insert 'comment' of a license ENTRY."
-  (let ((comment (guix-entry-value entry 'comment)))
-    (if (and comment
-             (string-match-p "^http" comment))
-        (guix-info-insert-value-simple comment 'guix-url)
-      (guix-info-insert-title-simple
-       (guix-info-param-title 'license 'comment))
-      (guix-info-insert-value-indent comment))))
-
-(defun guix-license-insert-file (entry)
-  "Insert button to open license definition."
-  (let ((license (guix-entry-value entry 'name)))
-    (guix-insert-button
-     (guix-license-file) 'guix-file
-     'help-echo (format "Open definition of license '%s'" license)
-     'action (lambda (btn)
-               (guix-find-license-definition (button-get btn 'license)))
-     'license license)))
-
-\f
-;;; License 'list'
-
-(guix-list-define-interface license
-  :buffer-name "*Guix Licenses*"
-  :get-entries-function 'guix-license-get-entries
-  :describe-function 'guix-license-list-describe
-  :message-function 'guix-license-message
-  :format '((name nil 40 t)
-            (url guix-list-get-url 50 t))
-  :titles '((name . "License"))
-  :sort-key '(name))
-
-(let ((map guix-license-list-mode-map))
-  (define-key map (kbd "e")   'guix-license-list-edit)
-  (define-key map (kbd "RET") 'guix-license-list-show-packages))
-
-(defun guix-license-list-describe (ids)
-  "Describe licenses with IDS (list of identifiers)."
-  (guix-buffer-display-entries
-   (guix-entries-by-ids ids (guix-buffer-current-entries))
-   'info 'license (cl-list* 'id ids) 'add))
-
-(defun guix-license-list-show-packages ()
-  "Display packages with the license at point."
-  (interactive)
-  (guix-packages-by-license (guix-list-current-id)))
-
-(defun guix-license-list-edit (&optional directory)
-  "Go to the location of the current license definition.
-See `guix-license-file' for the meaning of DIRECTORY."
-  (interactive (list (guix-read-directory)))
-  (guix-find-license-definition (guix-list-current-id) directory))
-
-\f
-;;; Interactive commands
-
-;;;###autoload
-(defun guix-licenses ()
-  "Display licenses of the Guix packages."
-  (interactive)
-  (guix-license-get-display 'all))
-
-(provide 'guix-ui-license)
-
-;;; guix-ui-license.el ends here
diff --git a/emacs/guix-ui-location.el b/emacs/guix-ui-location.el
deleted file mode 100644
index 0027c1f..0000000
--- a/emacs/guix-ui-location.el
+++ /dev/null
@@ -1,83 +0,0 @@
-;;; guix-ui-location.el --- Interface for displaying package locations
-
-;; Copyright © 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public Location as published by
-;; the Free Software Foundation, either version 3 of the Location, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public Location for more details.
-
-;; You should have received a copy of the GNU General Public Location
-;; along with this program.  If not, see <http://www.gnu.org/locations/>.
-
-;;; Commentary:
-
-;; This file provides a 'list' interface for displaying locations of Guix
-;; packages.
-
-;;; Code:
-
-(require 'guix-buffer)
-(require 'guix-list)
-(require 'guix-location)
-(require 'guix-backend)
-
-(guix-define-entry-type location)
-
-(defun guix-location-get-entries ()
-  "Receive 'package location' entries."
-  (guix-eval-read "(package-location-entries)"))
-
-\f
-;;; Location 'list'
-
-(guix-list-define-interface location
-  :buffer-name "*Guix Package Locations*"
-  :get-entries-function 'guix-location-get-entries
-  :format '((location guix-location-list-file-name-specification 50 t)
-            (number-of-packages nil 10 guix-list-sort-numerically-1
-                                :right-align t))
-  :sort-key '(location))
-
-(let ((map guix-location-list-mode-map))
-  (define-key map (kbd "RET") 'guix-location-list-show-packages)
-  ;; "Location Info" buffer is not defined (it would be useless), so
-  ;; unbind "i" key (by default, it is used to display Info buffer).
-  (define-key map (kbd "i") nil))
-
-(defun guix-location-list-file-name-specification (location &optional _)
-  "Return LOCATION button specification for `tabulated-list-entries'."
-  (list location
-        'face 'guix-list-file-name
-        'action (lambda (btn)
-                  (guix-find-location (button-get btn 'location)))
-        'follow-link t
-        'help-echo (concat "Find location: " location)
-        'location location))
-
-(declare-function guix-packages-by-location "guix-ui-package")
-
-(defun guix-location-list-show-packages ()
-  "Display packages placed in the location at point."
-  (interactive)
-  (guix-packages-by-location (guix-list-current-id)))
-
-\f
-;;; Interactive commands
-
-;;;###autoload
-(defun guix-locations ()
-  "Display locations of the Guix packages."
-  (interactive)
-  (guix-list-get-display-entries 'location))
-
-(provide 'guix-ui-location)
-
-;;; guix-ui-location.el ends here
diff --git a/emacs/guix-ui-package.el b/emacs/guix-ui-package.el
deleted file mode 100644
index 4280246..0000000
--- a/emacs/guix-ui-package.el
+++ /dev/null
@@ -1,1191 +0,0 @@
-;;; guix-ui-package.el --- Interface for displaying packages  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides an interface for displaying packages and outputs
-;; in 'list' and 'info' buffers, and commands for working with them.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-buffer)
-(require 'guix-list)
-(require 'guix-info)
-(require 'guix-ui)
-(require 'guix-base)
-(require 'guix-backend)
-(require 'guix-guile)
-(require 'guix-entry)
-(require 'guix-utils)
-(require 'guix-hydra)
-(require 'guix-hydra-build)
-(require 'guix-read)
-(require 'guix-license)
-(require 'guix-location)
-(require 'guix-profiles)
-
-(guix-ui-define-entry-type package)
-(guix-ui-define-entry-type output)
-
-(defcustom guix-package-list-type 'output
-  "Define how to display packages in 'list' buffer.
-Should be a symbol `package' or `output' (if `output', display each
-output on a separate line; if `package', display each package on
-a separate line)."
-  :type '(choice (const :tag "List of packages" package)
-                 (const :tag "List of outputs" output))
-  :group 'guix-package)
-
-(defcustom guix-package-info-type 'package
-  "Define how to display packages in 'info' buffer.
-Should be a symbol `package' or `output' (if `output', display
-each output separately; if `package', display outputs inside
-package data)."
-  :type '(choice (const :tag "Display packages" package)
-                 (const :tag "Display outputs" output))
-  :group 'guix-package)
-
-(defun guix-package-get-display (profile search-type &rest search-values)
-  "Search for packages/outputs and show results.
-
-If PROFILE is nil, use `guix-current-profile'.
-
-See `guix-ui-get-entries' for the meaning of SEARCH-TYPE and
-SEARCH-VALUES.
-
-Results are displayed in the list buffer, unless a single package
-is found and `guix-package-list-single' is nil."
-  (let* ((args    (cl-list* (or profile guix-current-profile)
-                            search-type search-values))
-         (entries (guix-buffer-get-entries
-                   'list guix-package-list-type args)))
-    (if (or guix-package-list-single
-            (null entries)
-            (cdr entries))
-        (guix-buffer-display-entries
-         entries 'list guix-package-list-type args 'add)
-      (guix-buffer-get-display-entries
-       'info guix-package-info-type args 'add))))
-
-(defun guix-package-entry->name-specification (entry &optional output)
-  "Return name specification of the package ENTRY and OUTPUT."
-  (guix-package-name-specification
-   (guix-entry-value entry 'name)
-   (guix-entry-value entry 'version)
-   (or output (guix-entry-value entry 'output))))
-
-(defun guix-package-entries->name-specifications (entries)
-  "Return name specifications by the package or output ENTRIES."
-  (cl-remove-duplicates (mapcar #'guix-package-entry->name-specification
-                                entries)
-                        :test #'string=))
-
-(defun guix-package-installed-outputs (entry)
-  "Return a list of installed outputs for the package ENTRY."
-  (mapcar (lambda (installed-entry)
-            (guix-entry-value installed-entry 'output))
-          (guix-entry-value entry 'installed)))
-
-(defun guix-package-id-and-output-by-output-id (output-id)
-  "Return a list (PACKAGE-ID OUTPUT) by OUTPUT-ID."
-  (cl-multiple-value-bind (package-id-str output)
-      (split-string output-id ":")
-    (let ((package-id (string-to-number package-id-str)))
-      (list (if (= 0 package-id) package-id-str package-id)
-            output))))
-
-(defun guix-package-build-log-file (id)
-  "Return build log file name of a package defined by ID."
-  (guix-eval-read
-   (guix-make-guile-expression 'package-build-log-file id)))
-
-(defun guix-package-find-build-log (id)
-  "Show build log of a package defined by ID."
-  (require 'guix-build-log)
-  (let ((file (guix-package-build-log-file id)))
-    (if file
-        (guix-build-log-find-file file)
-      (message "Couldn't find the package build log."))))
-
-\f
-;;; Processing package actions
-
-(defun guix-process-package-actions (profile actions
-                                     &optional operation-buffer)
-  "Process package ACTIONS on PROFILE.
-Each action is a list of the form:
-
-  (ACTION-TYPE PACKAGE-SPEC ...)
-
-ACTION-TYPE is one of the following symbols: `install',
-`upgrade', `remove'/`delete'.
-PACKAGE-SPEC should have the following form: (ID [OUTPUT] ...)."
-  (let (install upgrade remove)
-    (mapc (lambda (action)
-            (let ((action-type (car action))
-                  (specs (cdr action)))
-              (cl-case action-type
-                (install (setq install (append install specs)))
-                (upgrade (setq upgrade (append upgrade specs)))
-                ((remove delete) (setq remove (append remove specs))))))
-          actions)
-    (when (guix-continue-package-operation-p
-           profile
-           :install install :upgrade upgrade :remove remove)
-      (guix-eval-in-repl
-       (guix-make-guile-expression
-        'process-package-actions profile
-        :install install :upgrade upgrade :remove remove
-        :use-substitutes? (or guix-use-substitutes 'f)
-        :dry-run? (or guix-dry-run 'f))
-       (and (not guix-dry-run) operation-buffer)))))
-
-(cl-defun guix-continue-package-operation-p (profile
-                                             &key install upgrade remove)
-  "Return non-nil if a package operation should be continued.
-Ask a user if needed (see `guix-operation-confirm').
-INSTALL, UPGRADE, REMOVE are 'package action specifications'.
-See `guix-process-package-actions' for details."
-  (or (null guix-operation-confirm)
-      (let* ((entries (guix-ui-get-entries
-                       profile 'package 'id
-                       (append (mapcar #'car install)
-                               (mapcar #'car upgrade)
-                               (mapcar #'car remove))
-                       '(id name version location)))
-             (install-strings (guix-get-package-strings install entries))
-             (upgrade-strings (guix-get-package-strings upgrade entries))
-             (remove-strings  (guix-get-package-strings remove entries)))
-        (if (or install-strings upgrade-strings remove-strings)
-            (let ((buf (get-buffer-create guix-temp-buffer-name)))
-              (with-current-buffer buf
-                (setq-local cursor-type nil)
-                (setq buffer-read-only nil)
-                (erase-buffer)
-                (insert "Profile: " profile "\n\n")
-                (guix-insert-package-strings install-strings "install")
-                (guix-insert-package-strings upgrade-strings "upgrade")
-                (guix-insert-package-strings remove-strings "remove")
-                (let ((win (temp-buffer-window-show
-                            buf
-                            '((display-buffer-reuse-window
-                               display-buffer-at-bottom)
-                              (window-height . fit-window-to-buffer)))))
-                  (prog1 (guix-operation-prompt)
-                    (quit-window nil win)))))
-          (message "Nothing to be done.
-If Guix REPL was restarted, the data is not up-to-date.")
-          nil))))
-
-(defun guix-get-package-strings (specs entries)
-  "Return short package descriptions for performing package actions.
-See `guix-process-package-actions' for the meaning of SPECS.
-ENTRIES is a list of package entries to get info about packages."
-  (delq nil
-        (mapcar
-         (lambda (spec)
-           (let* ((id (car spec))
-                  (outputs (cdr spec))
-                  (entry (guix-entry-by-id id entries)))
-             (when entry
-               (let ((location (guix-entry-value entry 'location)))
-                 (concat (guix-package-entry->name-specification entry)
-                         (when outputs
-                           (concat ":"
-                                   (guix-concat-strings outputs ",")))
-                         (when location
-                           (concat "\t(" location ")")))))))
-         specs)))
-
-(defun guix-insert-package-strings (strings action)
-  "Insert information STRINGS at point for performing package ACTION."
-  (when strings
-    (insert "Package(s) to " (propertize action 'face 'bold) ":\n")
-    (mapc (lambda (str)
-            (insert "  " str "\n"))
-          strings)
-    (insert "\n")))
-
-\f
-;;; Package 'info'
-
-(guix-ui-info-define-interface package
-  :buffer-name "*Guix Package Info*"
-  :format '(guix-package-info-insert-heading
-            ignore
-            (synopsis ignore (simple guix-package-info-synopsis))
-            ignore
-            (description ignore (simple guix-package-info-description))
-            ignore
-            (outputs simple guix-package-info-insert-outputs)
-            guix-package-info-insert-misc
-            (source simple guix-package-info-insert-source)
-            (location simple guix-package-info-insert-location)
-            (home-url format (format guix-url))
-            (license format (format guix-package-license))
-            (systems format guix-package-info-insert-systems)
-            (inputs format (format guix-package-input))
-            (native-inputs format (format guix-package-native-input))
-            (propagated-inputs format
-                               (format guix-package-propagated-input)))
-  :titles '((home-url . "Home page")
-            (systems . "Supported systems"))
-  :required '(id name version installed non-unique))
-
-(guix-info-define-interface installed-output
-  :format '((path simple (indent guix-file))
-            (dependencies simple (indent guix-file)))
-  :titles '((path . "Store directory"))
-  :reduced? t)
-
-(defface guix-package-info-heading
-  '((t :inherit guix-info-heading))
-  "Face for package name and version headings."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-name
-  '((t :inherit font-lock-keyword-face))
-  "Face used for a name of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-name-button
-  '((t :inherit button))
-  "Face used for a full name that can be used to describe a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-version
-  '((t :inherit font-lock-builtin-face))
-  "Face used for a version of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-synopsis
-  '((((type tty pc) (class color)) :weight bold)
-    (t :height 1.1 :weight bold :inherit variable-pitch))
-  "Face used for a synopsis of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-description
-  '((t))
-  "Face used for a description of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-license
-  '((t :inherit font-lock-string-face))
-  "Face used for a license of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-location
-  '((t :inherit link))
-  "Face used for a location of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-source
-  '((t :inherit link :underline nil))
-  "Face used for a source URL of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-installed-outputs
-  '((default :weight bold)
-    (((class color) (min-colors 88) (background light))
-     :foreground "ForestGreen")
-    (((class color) (min-colors 88) (background dark))
-     :foreground "PaleGreen")
-    (((class color) (min-colors 8))
-     :foreground "green")
-    (t :underline t))
-  "Face used for installed outputs of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-uninstalled-outputs
-  '((t :weight bold))
-  "Face used for uninstalled outputs of a package."
-  :group 'guix-package-info-faces)
-
-(defface guix-package-info-obsolete
-  '((t :inherit error))
-  "Face used if a package is obsolete."
-  :group 'guix-package-info-faces)
-
-(defcustom guix-package-info-auto-find-package t
-  "If non-nil, open store directory after pressing \"Show\" package button.
-If nil, just display the store directory (or directories) without finding."
-  :type 'boolean
-  :group 'guix-package-info)
-
-(defcustom guix-package-info-auto-find-source nil
-  "If non-nil, open source file after pressing \"Show\" source button.
-If nil, just display the source file name without finding."
-  :type 'boolean
-  :group 'guix-package-info)
-
-(defcustom guix-package-info-auto-download-source t
-  "If nil, do not automatically download a source file if it doesn't exist.
-After pressing a \"Show\" button, a derivation of the package
-source is calculated and a store file path is displayed.  If this
-variable is non-nil and the source file does not exist in the
-store, it will be automatically downloaded (with a possible
-prompt depending on `guix-operation-confirm' variable)."
-  :type 'boolean
-  :group 'guix-package-info)
-
-(defcustom guix-package-info-button-functions
-  '(guix-package-info-insert-build-button
-    guix-package-info-insert-build-log-button)
-  "List of functions used to insert package buttons in Info buffer.
-Each function is called with 2 arguments: package ID and full name."
-  :type '(repeat function)
-  :group 'guix-package-info)
-
-(defvar guix-package-info-download-buffer nil
-  "Buffer from which a current download operation was performed.")
-
-(defvar guix-package-info-output-format "%-10s"
-  "String used to format output names of the packages.
-It should be a '%s'-sequence.  After inserting an output name
-formatted with this string, an action button is inserted.")
-
-(defvar guix-package-info-obsolete-string "(This package is obsolete)"
-  "String used if a package is obsolete.")
-
-(define-button-type 'guix-package-location
-  :supertype 'guix
-  'face 'guix-package-info-location
-  'help-echo "Find location of this package"
-  'action (lambda (btn)
-            (guix-find-location (button-label btn))))
-
-(define-button-type 'guix-package-license
-  :supertype 'guix
-  'face 'guix-package-info-license
-  'help-echo "Display license info"
-  'action (lambda (btn)
-            (require 'guix-ui-license)
-            (guix-buffer-get-display-entries
-             'info 'license
-             (list 'name (button-label btn))
-             'add)))
-
-(define-button-type 'guix-package-name
-  :supertype 'guix
-  'face 'guix-package-info-name-button
-  'help-echo "Describe this package"
-  'action (lambda (btn)
-            (guix-buffer-get-display-entries-current
-             'info guix-package-info-type
-             (list (guix-ui-current-profile)
-                   'name (or (button-get btn 'spec)
-                             (button-label btn)))
-             'add)))
-
-(define-button-type 'guix-package-heading
-  :supertype 'guix-package-name
-  'face 'guix-package-info-heading)
-
-(define-button-type 'guix-package-source
-  :supertype 'guix
-  'face 'guix-package-info-source
-  'help-echo ""
-  'action (lambda (_)
-            ;; As a source may not be a real URL (e.g., "mirror://..."),
-            ;; no action is bound to a source button.
-            (message "Yes, this is the source URL. What did you expect?")))
-
-(defun guix-package-info-insert-heading (entry)
-  "Insert package ENTRY heading (name and version) at point."
-  (guix-insert-button
-   (concat (guix-entry-value entry 'name) " "
-           (guix-entry-value entry 'version))
-   'guix-package-heading
-   'spec (guix-package-entry->name-specification entry)))
-
-(defun guix-package-info-insert-location (location &optional _)
-  "Insert package LOCATION at point."
-  (if (null location)
-      (guix-format-insert nil)
-    (let ((location-file (car (split-string location ":"))))
-      (guix-info-insert-value-indent location 'guix-package-location)
-      ;; Do not show "Packages" button if a package 'from file' is displayed.
-      (unless (eq (guix-ui-current-search-type) 'from-file)
-        (guix-info-insert-indent)
-        (guix-info-insert-action-button
-         "Packages"
-         (lambda (btn)
-           (guix-package-get-display (guix-ui-current-profile)
-                                     'location
-                                     (button-get btn 'location)))
-         (format "Display packages from location '%s'" location-file)
-         'location location-file)))))
-
-(defun guix-package-info-insert-systems (systems entry)
-  "Insert supported package SYSTEMS at point."
-  (guix-info-insert-value-format
-   systems 'guix-hydra-build-system
-   'action (lambda (btn)
-             (let ((args (guix-hydra-build-latest-prompt-args
-                          :job (button-get btn 'job-name)
-                          :system (button-label btn))))
-               (apply #'guix-hydra-build-get-display
-                      'latest args)))
-   'job-name (guix-hydra-job-name-specification
-              (guix-entry-value entry 'name)
-              (guix-entry-value entry 'version))))
-
-(defmacro guix-package-info-define-insert-inputs (&optional type)
-  "Define a face and a function for inserting package inputs.
-TYPE is a type of inputs.
-Function name is `guix-package-info-insert-TYPE-inputs'.
-Face name is `guix-package-info-TYPE-inputs'."
-  (let* ((type-str (symbol-name type))
-         (type-name (and type (concat type-str "-")))
-         (type-desc (and type (concat type-str " ")))
-         (face (intern (concat "guix-package-info-" type-name "inputs")))
-         (btn  (intern (concat "guix-package-" type-name "input"))))
-    `(progn
-       (defface ,face
-         '((t :inherit guix-package-info-name-button))
-         ,(concat "Face used for " type-desc "inputs of a package.")
-         :group 'guix-package-info-faces)
-
-       (define-button-type ',btn
-         :supertype 'guix-package-name
-         'face ',face))))
-
-(guix-package-info-define-insert-inputs)
-(guix-package-info-define-insert-inputs native)
-(guix-package-info-define-insert-inputs propagated)
-
-(defun guix-package-info-insert-outputs (outputs entry)
-  "Insert OUTPUTS from package ENTRY at point."
-  (and (guix-entry-value entry 'obsolete)
-       (guix-package-info-insert-obsolete-text))
-  (and (guix-entry-value entry 'non-unique)
-       (guix-entry-value entry 'installed)
-       (guix-package-info-insert-non-unique-text
-        (guix-package-entry->name-specification entry)))
-  (insert "\n")
-  (dolist (output outputs)
-    (guix-package-info-insert-output output entry)))
-
-(defun guix-package-info-insert-obsolete-text ()
-  "Insert a message about obsolete package at point."
-  (guix-info-insert-indent)
-  (guix-format-insert guix-package-info-obsolete-string
-                      'guix-package-info-obsolete))
-
-(defun guix-package-info-insert-non-unique-text (full-name)
-  "Insert a message about non-unique package with FULL-NAME at point."
-  (insert "\n")
-  (guix-info-insert-indent)
-  (insert "Installed outputs are displayed for a non-unique ")
-  (guix-insert-button full-name 'guix-package-name)
-  (insert " package."))
-
-(defun guix-package-info-insert-output (output entry)
-  "Insert OUTPUT at point.
-Make some fancy text with buttons and additional stuff if the
-current OUTPUT is installed (if there is such output in
-`installed' parameter of a package ENTRY)."
-  (let* ((installed (guix-entry-value entry 'installed))
-         (obsolete  (guix-entry-value entry 'obsolete))
-         (installed-entry (cl-find-if
-                           (lambda (entry)
-                             (string= (guix-entry-value entry 'output)
-                                      output))
-                           installed))
-         (action-type (if installed-entry 'delete 'install))
-         (profile (guix-ui-current-profile)))
-    (guix-info-insert-indent)
-    (guix-format-insert output
-                        (if installed-entry
-                            'guix-package-info-installed-outputs
-                          'guix-package-info-uninstalled-outputs)
-                        guix-package-info-output-format)
-    ;; Do not allow a user to install/delete anything to/from a system
-    ;; profile, so add action buttons only for non-system profiles.
-    (when (and profile
-               (not (guix-system-profile? profile)))
-      (guix-package-info-insert-action-button action-type entry output)
-      (when obsolete
-        (guix-info-insert-indent)
-        (guix-package-info-insert-action-button 'upgrade entry output)))
-    (insert "\n")
-    (when installed-entry
-      (guix-info-insert-entry installed-entry 'installed-output 2))))
-
-(defun guix-package-info-insert-action-button (type entry output)
-  "Insert button to process an action on a package OUTPUT at point.
-TYPE is one of the following symbols: `install', `delete', `upgrade'.
-ENTRY is an alist with package info."
-  (let ((type-str  (capitalize (symbol-name type)))
-        (full-name (guix-package-entry->name-specification entry output)))
-    (guix-info-insert-action-button
-     type-str
-     (lambda (btn)
-       (guix-process-package-actions
-        (guix-ui-current-profile)
-        `((,(button-get btn 'action-type) (,(button-get btn 'id)
-                                           ,(button-get btn 'output))))
-        (current-buffer)))
-     (concat type-str " '" full-name "'")
-     'action-type type
-     'id (or (guix-entry-value entry 'package-id)
-             (guix-entry-id entry))
-     'output output)))
-
-(defun guix-package-info-show-store-path (entry-id package-id)
-  "Show store directories of the package outputs in the current buffer.
-ENTRY-ID is an ID of the current entry (package or output).
-PACKAGE-ID is an ID of the package which store path to show."
-  (let* ((entries (guix-buffer-current-entries))
-         (entry   (guix-entry-by-id entry-id entries))
-         (dirs    (guix-package-store-path package-id)))
-    (or dirs
-        (error "Couldn't define store directory of the package"))
-    (let* ((new-entry (cons (cons 'store-path dirs)
-                            entry))
-           (new-entries (guix-replace-entry entry-id new-entry entries)))
-      (setf (guix-buffer-item-entries guix-buffer-item)
-            new-entries)
-      (guix-buffer-redisplay-goto-button)
-      (let ((dir (car dirs)))
-        (if (file-exists-p dir)
-            (if guix-package-info-auto-find-package
-                (find-file dir)
-              (message nil))
-          (message "'%s' does not exist.\nTry to build this package."
-                   dir))))))
-
-(defun guix-package-info-insert-misc (entry)
-  "Insert various buttons and other info for package ENTRY at point."
-  (if (guix-entry-value entry 'obsolete)
-      (guix-format-insert nil)
-    (let* ((entry-id   (guix-entry-id entry))
-           (package-id (or (guix-entry-value entry 'package-id)
-                           entry-id))
-           (full-name  (guix-package-entry->name-specification entry))
-           (store-path (guix-entry-value entry 'store-path)))
-      (guix-info-insert-title-simple "Package")
-      (if store-path
-          (guix-info-insert-value-indent store-path 'guix-file)
-        (guix-info-insert-action-button
-         "Show"
-         (lambda (btn)
-           (guix-package-info-show-store-path
-            (button-get btn 'entry-id)
-            (button-get btn 'package-id)))
-         "Show the store directory of the current package"
-         'entry-id entry-id
-         'package-id package-id))
-      (when guix-package-info-button-functions
-        (insert "\n")
-        (guix-mapinsert (lambda (fun)
-                          (funcall fun package-id full-name))
-                        guix-package-info-button-functions
-                        (guix-info-get-indent)
-                        :indent guix-info-indent
-                        :column (guix-info-fill-column))))))
-
-(defun guix-package-info-insert-build-button (id full-name)
-  "Insert button to build a package defined by ID."
-  (guix-info-insert-action-button
-   "Build"
-   (lambda (btn)
-     (guix-build-package (button-get btn 'id)
-                         (format "Build '%s' package?" full-name)))
-   (format "Build the current package")
-   'id id))
-
-(defun guix-package-info-insert-build-log-button (id _name)
-  "Insert button to show build log of a package defined by ID."
-  (guix-info-insert-action-button
-   "Build Log"
-   (lambda (btn)
-     (guix-package-find-build-log (button-get btn 'id)))
-   "View build log of the current package"
-   'id id))
-
-(defun guix-package-info-show-source (entry-id package-id)
-  "Show file name of a package source in the current info buffer.
-Find the file if needed (see `guix-package-info-auto-find-source').
-ENTRY-ID is an ID of the current entry (package or output).
-PACKAGE-ID is an ID of the package which source to show."
-  (let* ((entries (guix-buffer-current-entries))
-         (entry   (guix-entry-by-id entry-id entries))
-         (file    (guix-package-source-path package-id)))
-    (or file
-        (error "Couldn't define file name of the package source"))
-    (let* ((new-entry (cons (cons 'source-file file)
-                            entry))
-           (new-entries (guix-replace-entry entry-id new-entry entries)))
-      (setf (guix-buffer-item-entries guix-buffer-item)
-            new-entries)
-      (guix-buffer-redisplay-goto-button)
-      (if (file-exists-p file)
-          (if guix-package-info-auto-find-source
-              (guix-find-file file)
-            (message "The source store path is displayed."))
-        (if guix-package-info-auto-download-source
-            (guix-package-info-download-source package-id)
-          (message "The source does not exist in the store."))))))
-
-(defun guix-package-info-download-source (package-id)
-  "Download a source of the package PACKAGE-ID."
-  (setq guix-package-info-download-buffer (current-buffer))
-  (guix-package-source-build-derivation
-   package-id
-   "The source does not exist in the store. Download it?"))
-
-(defun guix-package-info-insert-source (source entry)
-  "Insert SOURCE from package ENTRY at point.
-SOURCE is a list of URLs."
-  (if (null source)
-      (guix-format-insert nil)
-    (let* ((source-file (guix-entry-value entry 'source-file))
-           (entry-id    (guix-entry-id entry))
-           (package-id  (or (guix-entry-value entry 'package-id)
-                            entry-id)))
-      (if (null source-file)
-          (guix-info-insert-action-button
-           "Show"
-           (lambda (btn)
-             (guix-package-info-show-source (button-get btn 'entry-id)
-                                            (button-get btn 'package-id)))
-           "Show the source store directory of the current package"
-           'entry-id entry-id
-           'package-id package-id)
-        (unless (file-exists-p source-file)
-          (guix-info-insert-action-button
-           "Download"
-           (lambda (btn)
-             (guix-package-info-download-source
-              (button-get btn 'package-id)))
-           "Download the source into the store"
-           'package-id package-id))
-        (guix-info-insert-value-indent source-file 'guix-file))
-      (guix-info-insert-value-indent source 'guix-package-source))))
-
-(defun guix-package-info-redisplay-after-download ()
-  "Redisplay an 'info' buffer after downloading the package source.
-This function is used to hide a \"Download\" button if needed."
-  (when (buffer-live-p guix-package-info-download-buffer)
-    (with-current-buffer guix-package-info-download-buffer
-      (guix-buffer-redisplay-goto-button))
-    (setq guix-package-info-download-buffer nil)))
-
-(add-hook 'guix-after-source-download-hook
-          'guix-package-info-redisplay-after-download)
-
-\f
-;;; Package 'list'
-
-(guix-ui-list-define-interface package
-  :buffer-name "*Guix Package List*"
-  :format '((name guix-package-list-get-name 20 t)
-            (version nil 10 nil)
-            (outputs nil 13 t)
-            (installed guix-package-list-get-installed-outputs 13 t)
-            (synopsis guix-list-get-one-line 30 nil))
-  :sort-key '(name)
-  :marks '((install . ?I)
-           (upgrade . ?U)
-           (delete  . ?D)))
-
-(let ((map guix-package-list-mode-map))
-  (define-key map (kbd "B")   'guix-package-list-latest-builds)
-  (define-key map (kbd "e")   'guix-package-list-edit)
-  (define-key map (kbd "x")   'guix-package-list-execute)
-  (define-key map (kbd "i")   'guix-package-list-mark-install)
-  (define-key map (kbd "d")   'guix-package-list-mark-delete)
-  (define-key map (kbd "U")   'guix-package-list-mark-upgrade)
-  (define-key map (kbd "^")   'guix-package-list-mark-upgrades))
-
-(defface guix-package-list-installed
-  '((t :inherit guix-package-info-installed-outputs))
-  "Face used if there are installed outputs for the current package."
-  :group 'guix-package-list-faces)
-
-(defface guix-package-list-obsolete
-  '((t :inherit guix-package-info-obsolete))
-  "Face used if a package is obsolete."
-  :group 'guix-package-list-faces)
-
-(defcustom guix-package-list-generation-marking-enabled nil
-  "If non-nil, allow putting marks in a list with 'generation packages'.
-
-By default this is disabled, because it may be confusing.  For
-example, a package is installed in some generation, so a user can
-mark it for deletion in the list of packages from this
-generation, but the package may not be installed in the latest
-generation, so actually it cannot be deleted.
-
-If you managed to understand the explanation above or if you
-really know what you do or if you just don't care, you can set
-this variable to t.  It should not do much harm anyway (most
-likely)."
-  :type 'boolean
-  :group 'guix-package-list)
-
-(defun guix-package-list-get-name (name entry)
-  "Return NAME of the package ENTRY.
-Colorize it with `guix-package-list-installed' or
-`guix-package-list-obsolete' if needed."
-  (guix-get-string name
-                   (cond ((guix-entry-value entry 'obsolete)
-                          'guix-package-list-obsolete)
-                         ((guix-entry-value entry 'installed)
-                          'guix-package-list-installed))))
-
-(defun guix-package-list-get-installed-outputs (installed &optional _)
-  "Return string with outputs from INSTALLED entries."
-  (guix-get-string
-   (mapcar (lambda (entry)
-             (guix-entry-value entry 'output))
-           installed)))
-
-(defun guix-package-list-marking-check ()
-  "Signal an error if marking is disabled for the current buffer."
-  (when (and (not guix-package-list-generation-marking-enabled)
-             (or (derived-mode-p 'guix-package-list-mode)
-                 (derived-mode-p 'guix-output-list-mode))
-             (eq (guix-ui-current-search-type) 'generation))
-    (error "Action marks are disabled for lists of 'generation packages'")))
-
-(defun guix-package-list-mark-outputs (mark default
-                                       &optional prompt available)
-  "Mark the current package with MARK and move to the next line.
-If PROMPT is non-nil, use it to ask a user for outputs from
-AVAILABLE list, otherwise mark all DEFAULT outputs."
-  (let ((outputs (if prompt
-                     (guix-completing-read-multiple
-                      prompt available nil t)
-                   default)))
-    (apply #'guix-list--mark mark t outputs)))
-
-(defun guix-package-list-mark-install (&optional arg)
-  "Mark the current package for installation and move to the next line.
-With ARG, prompt for the outputs to install (several outputs may
-be separated with \",\")."
-  (interactive "P")
-  (guix-package-list-marking-check)
-  (let* ((entry     (guix-list-current-entry))
-         (all       (guix-entry-value entry 'outputs))
-         (installed (guix-package-installed-outputs entry))
-         (available (cl-set-difference all installed :test #'string=)))
-    (or available
-        (user-error "This package is already installed"))
-    (guix-package-list-mark-outputs
-     'install '("out")
-     (and arg "Output(s) to install: ")
-     available)))
-
-(defun guix-package-list-mark-delete (&optional arg)
-  "Mark the current package for deletion and move to the next line.
-With ARG, prompt for the outputs to delete (several outputs may
-be separated with \",\")."
-  (interactive "P")
-  (guix-package-list-marking-check)
-  (let* ((entry (guix-list-current-entry))
-         (installed (guix-package-installed-outputs entry)))
-    (or installed
-        (user-error "This package is not installed"))
-    (guix-package-list-mark-outputs
-     'delete installed
-     (and arg "Output(s) to delete: ")
-     installed)))
-
-(defun guix-package-list-mark-upgrade (&optional arg)
-  "Mark the current package for upgrading and move to the next line.
-With ARG, prompt for the outputs to upgrade (several outputs may
-be separated with \",\")."
-  (interactive "P")
-  (guix-package-list-marking-check)
-  (let* ((entry (guix-list-current-entry))
-         (installed (guix-package-installed-outputs entry)))
-    (or installed
-        (user-error "This package is not installed"))
-    (when (or (guix-entry-value entry 'obsolete)
-              (y-or-n-p "This package is not obsolete.  Try to upgrade it anyway? "))
-      (guix-package-list-mark-outputs
-       'upgrade installed
-       (and arg "Output(s) to upgrade: ")
-       installed))))
-
-(defun guix-package-mark-upgrades (fun)
-  "Mark all obsolete packages for upgrading.
-Use FUN to perform marking of the current line.  FUN should
-take an entry as argument."
-  (guix-package-list-marking-check)
-  (let ((obsolete (cl-remove-if-not
-                   (lambda (entry)
-                     (guix-entry-value entry 'obsolete))
-                   (guix-buffer-current-entries))))
-    (guix-list-for-each-line
-     (lambda ()
-       (let* ((id (guix-list-current-id))
-              (entry (cl-find-if
-                      (lambda (entry)
-                        (equal id (guix-entry-id entry)))
-                      obsolete)))
-         (when entry
-           (funcall fun entry)))))))
-
-(defun guix-package-list-mark-upgrades ()
-  "Mark all obsolete packages for upgrading."
-  (interactive)
-  (guix-package-mark-upgrades
-   (lambda (entry)
-     (apply #'guix-list--mark
-            'upgrade nil
-            (guix-package-installed-outputs entry)))))
-
-(defun guix-package-assert-non-system-profile ()
-  "Verify that the current profile is not a system one.
-The current profile is the one used by the current buffer."
-  (let ((profile (guix-ui-current-profile)))
-    (and profile
-         (guix-system-profile? profile)
-         (user-error "Packages cannot be installed or removed to/from \
-profile '%s'.
-Use 'guix system reconfigure' shell command to modify a system profile."
-                     profile))))
-
-(defun guix-package-execute-actions (fun)
-  "Perform actions on the marked packages.
-Use FUN to define actions suitable for `guix-process-package-actions'.
-FUN should take action-type as argument."
-  (guix-package-assert-non-system-profile)
-  (let ((actions (delq nil
-                       (mapcar fun '(install delete upgrade)))))
-    (if actions
-        (guix-process-package-actions (guix-ui-current-profile)
-                                      actions (current-buffer))
-      (user-error "No operations specified"))))
-
-(defun guix-package-list-execute ()
-  "Perform actions on the marked packages."
-  (interactive)
-  (guix-package-execute-actions #'guix-package-list-make-action))
-
-(defun guix-package-list-make-action (action-type)
-  "Return action specification for the packages marked with ACTION-TYPE.
-Return nil, if there are no packages marked with ACTION-TYPE.
-The specification is suitable for `guix-process-package-actions'."
-  (let ((specs (guix-list-get-marked-args action-type)))
-    (and specs (cons action-type specs))))
-
-(defun guix-package-list-edit (&optional directory)
-  "Go to the location of the current package.
-See `guix-find-location' for the meaning of DIRECTORY."
-  (interactive (list (guix-read-directory)))
-  (guix-edit (guix-list-current-id) directory))
-
-(defun guix-package-list-latest-builds (number &rest args)
-  "Display latest NUMBER of Hydra builds of the current package.
-Interactively, prompt for NUMBER.  With prefix argument, prompt
-for all ARGS."
-  (interactive
-   (let ((entry (guix-list-current-entry)))
-     (guix-hydra-build-latest-prompt-args
-      :job (guix-hydra-job-name-specification
-            (guix-entry-value entry 'name)
-            (guix-entry-value entry 'version)))))
-  (apply #'guix-hydra-latest-builds number args))
-
-\f
-;;; Output 'info'
-
-(guix-ui-info-define-interface output
-  :buffer-name "*Guix Package Info*"
-  :format '((name format (format guix-package-info-name))
-            (version format guix-output-info-insert-version)
-            (output format guix-output-info-insert-output)
-            (synopsis simple (indent guix-package-info-synopsis))
-            guix-package-info-insert-misc
-            (source simple guix-package-info-insert-source)
-            (path simple (indent guix-file))
-            (dependencies simple (indent guix-file))
-            (location simple guix-package-info-insert-location)
-            (home-url format (format guix-url))
-            (license format (format guix-package-license))
-            (systems format guix-package-info-insert-systems)
-            (inputs format (format guix-package-input))
-            (native-inputs format (format guix-package-native-input))
-            (propagated-inputs format
-                               (format guix-package-propagated-input))
-            (description simple (indent guix-package-info-description)))
-  :titles guix-package-info-titles
-  :required '(id package-id installed non-unique))
-
-(defun guix-output-info-insert-version (version entry)
-  "Insert output VERSION and obsolete text if needed at point."
-  (guix-info-insert-value-format version
-                                 'guix-package-info-version)
-  (and (guix-entry-value entry 'obsolete)
-       (guix-package-info-insert-obsolete-text)))
-
-(defun guix-output-info-insert-output (output entry)
-  "Insert OUTPUT and action buttons at point."
-  (let* ((installed   (guix-entry-value entry 'installed))
-         (obsolete    (guix-entry-value entry 'obsolete))
-         (action-type (if installed 'delete 'install)))
-    (guix-info-insert-value-format
-     output
-     (if installed
-         'guix-package-info-installed-outputs
-       'guix-package-info-uninstalled-outputs))
-    (guix-info-insert-indent)
-    (guix-package-info-insert-action-button action-type entry output)
-    (when obsolete
-      (guix-info-insert-indent)
-      (guix-package-info-insert-action-button 'upgrade entry output))))
-
-\f
-;;; Output 'list'
-
-(guix-ui-list-define-interface output
-  :buffer-name "*Guix Package List*"
-  :describe-function 'guix-output-list-describe
-  :format '((name guix-package-list-get-name 20 t)
-            (version nil 10 nil)
-            (output nil 9 t)
-            (installed nil 12 t)
-            (synopsis guix-list-get-one-line 30 nil))
-  :required '(id package-id)
-  :sort-key '(name)
-  :marks '((install . ?I)
-           (upgrade . ?U)
-           (delete  . ?D)))
-
-(let ((map guix-output-list-mode-map))
-  (define-key map (kbd "B")   'guix-package-list-latest-builds)
-  (define-key map (kbd "e")   'guix-output-list-edit)
-  (define-key map (kbd "x")   'guix-output-list-execute)
-  (define-key map (kbd "i")   'guix-output-list-mark-install)
-  (define-key map (kbd "d")   'guix-output-list-mark-delete)
-  (define-key map (kbd "U")   'guix-output-list-mark-upgrade)
-  (define-key map (kbd "^")   'guix-output-list-mark-upgrades))
-
-(defun guix-output-list-mark-install ()
-  "Mark the current output for installation and move to the next line."
-  (interactive)
-  (guix-package-list-marking-check)
-  (let* ((entry     (guix-list-current-entry))
-         (installed (guix-entry-value entry 'installed)))
-    (if installed
-        (user-error "This output is already installed")
-      (guix-list--mark 'install t))))
-
-(defun guix-output-list-mark-delete ()
-  "Mark the current output for deletion and move to the next line."
-  (interactive)
-  (guix-package-list-marking-check)
-  (let* ((entry     (guix-list-current-entry))
-         (installed (guix-entry-value entry 'installed)))
-    (if installed
-        (guix-list--mark 'delete t)
-      (user-error "This output is not installed"))))
-
-(defun guix-output-list-mark-upgrade ()
-  "Mark the current output for upgrading and move to the next line."
-  (interactive)
-  (guix-package-list-marking-check)
-  (let* ((entry     (guix-list-current-entry))
-         (installed (guix-entry-value entry 'installed)))
-    (or installed
-        (user-error "This output is not installed"))
-    (when (or (guix-entry-value entry 'obsolete)
-              (y-or-n-p "This output is not obsolete.  Try to upgrade it anyway? "))
-      (guix-list--mark 'upgrade t))))
-
-(defun guix-output-list-mark-upgrades ()
-  "Mark all obsolete package outputs for upgrading."
-  (interactive)
-  (guix-package-mark-upgrades
-   (lambda (_) (guix-list--mark 'upgrade))))
-
-(defun guix-output-list-execute ()
-  "Perform actions on the marked outputs."
-  (interactive)
-  (guix-package-execute-actions #'guix-output-list-make-action))
-
-(defun guix-output-list-make-action (action-type)
-  "Return action specification for the outputs marked with ACTION-TYPE.
-Return nil, if there are no outputs marked with ACTION-TYPE.
-The specification is suitable for `guix-process-output-actions'."
-  (let ((ids (guix-list-get-marked-id-list action-type)))
-    (and ids (cons action-type
-                   (mapcar #'guix-package-id-and-output-by-output-id
-                           ids)))))
-
-(defun guix-output-list-describe (ids)
-  "Describe outputs with IDS (list of output identifiers).
-See `guix-package-info-type'."
-  (if (eq guix-package-info-type 'output)
-      (guix-buffer-get-display-entries
-       'info 'output
-       (cl-list* (guix-ui-current-profile) 'id ids)
-       'add)
-    (let ((pids (mapcar (lambda (oid)
-                          (car (guix-package-id-and-output-by-output-id
-                                oid)))
-                        ids)))
-      (guix-buffer-get-display-entries
-       'info 'package
-       (cl-list* (guix-ui-current-profile)
-                 'id (cl-remove-duplicates pids))
-       'add))))
-
-(defun guix-output-list-edit (&optional directory)
-  "Go to the location of the current package.
-See `guix-find-location' for the meaning of DIRECTORY."
-  (interactive (list (guix-read-directory)))
-  (guix-edit (guix-entry-value (guix-list-current-entry)
-                               'package-id)
-             directory))
-
-\f
-;;; Interactive commands
-
-(defvar guix-package-search-params '(name synopsis description)
-  "Default list of package parameters for searching by regexp.")
-
-(defvar guix-package-search-history nil
-  "A history of minibuffer prompts.")
-
-;;;###autoload
-(defun guix-packages-by-name (name &optional profile)
-  "Display Guix packages with NAME.
-NAME is a string with name specification.  It may optionally contain
-a version number.  Examples: \"guile\", \"guile@2.0.11\".
-
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (guix-read-package-name)
-         (guix-ui-read-profile)))
-  (guix-package-get-display profile 'name name))
-
-;;;###autoload
-(defun guix-packages-by-license (license &optional profile)
-  "Display Guix packages with LICENSE.
-LICENSE is a license name string.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (guix-read-license-name)
-         (guix-ui-read-profile)))
-  (guix-package-get-display profile 'license license))
-
-;;;###autoload
-(defun guix-packages-by-location (location &optional profile)
-  "Display Guix packages placed in LOCATION file.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (guix-read-package-location)
-         (guix-ui-read-profile)))
-  (guix-package-get-display profile 'location location))
-
-;;;###autoload
-(defun guix-package-from-file (file &optional profile)
-  "Display Guix package that the code from FILE evaluates to.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (read-file-name "File with package: ")
-         (guix-ui-read-profile)))
-  (guix-buffer-get-display-entries
-   'info 'package
-   (list (or profile guix-current-profile) 'from-file file)
-   'add))
-
-;;;###autoload
-(defun guix-search-by-regexp (regexp &optional params profile)
-  "Search for Guix packages by REGEXP.
-PARAMS are package parameters that should be searched.
-If PARAMS are not specified, use `guix-package-search-params'.
-
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (read-regexp "Regexp: " nil 'guix-package-search-history)
-         nil (guix-ui-read-profile)))
-  (guix-package-get-display profile 'regexp regexp
-                            (or params guix-package-search-params)))
-
-;;;###autoload
-(defun guix-search-by-name (regexp &optional profile)
-  "Search for Guix packages matching REGEXP in a package name.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive
-   (list (read-string "Package name by regexp: "
-                      nil 'guix-package-search-history)
-         (guix-ui-read-profile)))
-  (guix-search-by-regexp regexp '(name) profile))
-
-;;;###autoload
-(defun guix-installed-packages (&optional profile)
-  "Display information about installed Guix packages.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive (list (guix-ui-read-profile)))
-  (guix-package-get-display profile 'installed))
-
-;;;###autoload
-(defun guix-installed-user-packages ()
-  "Display information about Guix packages installed in a user profile."
-  (interactive)
-  (guix-installed-packages guix-user-profile))
-
-;;;###autoload
-(defun guix-installed-system-packages ()
-  "Display information about Guix packages installed in a system profile."
-  (interactive)
-  (guix-installed-packages
-   (guix-packages-profile guix-system-profile nil t)))
-
-;;;###autoload
-(defun guix-obsolete-packages (&optional profile)
-  "Display information about obsolete Guix packages.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive (list (guix-ui-read-profile)))
-  (guix-package-get-display profile 'obsolete))
-
-;;;###autoload
-(defun guix-all-available-packages (&optional profile)
-  "Display information about all available Guix packages.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive (list (guix-ui-read-profile)))
-  (guix-package-get-display profile 'all-available))
-
-;;;###autoload
-(defun guix-newest-available-packages (&optional profile)
-  "Display information about the newest available Guix packages.
-If PROFILE is nil, use `guix-current-profile'.
-Interactively with prefix, prompt for PROFILE."
-  (interactive (list (guix-ui-read-profile)))
-  (guix-package-get-display profile 'newest-available))
-
-(provide 'guix-ui-package)
-
-;;; guix-ui-package.el ends here
diff --git a/emacs/guix-ui-system-generation.el b/emacs/guix-ui-system-generation.el
deleted file mode 100644
index 7f4d76d..0000000
--- a/emacs/guix-ui-system-generation.el
+++ /dev/null
@@ -1,105 +0,0 @@
-;;; guix-ui-system-generation.el --- Interface for displaying system generations  -*- lexical-binding: t -*-
-
-;; Copyright © 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides an interface for displaying system generations
-;; in 'list' and 'info' buffers, and commands for working with them.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-list)
-(require 'guix-ui)
-(require 'guix-ui-generation)
-(require 'guix-profiles)
-
-(guix-ui-define-entry-type system-generation)
-
-(defun guix-system-generation-get-display (search-type &rest search-values)
-  "Search for system generations and show results.
-See `guix-ui-get-entries' for the meaning of SEARCH-TYPE and
-SEARCH-VALUES."
-  (apply #'guix-list-get-display-entries
-         'system-generation
-         guix-system-profile
-         search-type search-values))
-
-\f
-;;; System generation 'info'
-
-(guix-ui-info-define-interface system-generation
-  :buffer-name "*Guix Generation Info*"
-  :format '((number format guix-generation-info-insert-number)
-            (label format (format))
-            (prev-number format (format))
-            (current format guix-generation-info-insert-current)
-            (path format (format guix-file))
-            (time format (time))
-            (root-device format (format))
-            (kernel format (format guix-file)))
-  :titles guix-generation-info-titles)
-
-\f
-;;; System generation 'list'
-
-;; FIXME It is better to make `guix-generation-list-shared-map' with
-;; common keys for both usual and system generations.
-(defvar guix-system-generation-list-mode-map
-  (copy-keymap guix-generation-list-mode-map)
-  "Keymap for `guix-system-generation-list-mode' buffers.")
-
-(guix-ui-list-define-interface system-generation
-  :buffer-name "*Guix Generation List*"
-  :format '((number nil 5 guix-list-sort-numerically-0 :right-align t)
-            (current guix-generation-list-get-current 10 t)
-            (label nil 40 t)
-            (time guix-list-get-time 20 t)
-            (path guix-list-get-file-name 30 t))
-  :titles guix-generation-list-titles
-  :sort-key '(number . t)
-  :marks '((delete . ?D)))
-
-\f
-;;; Interactive commands
-
-;;;###autoload
-(defun guix-system-generations ()
-  "Display information about system generations."
-  (interactive)
-  (guix-system-generation-get-display 'all))
-
-;;;###autoload
-(defun guix-last-system-generations (number)
-  "Display information about last NUMBER of system generations."
-  (interactive "nThe number of last generations: ")
-  (guix-system-generation-get-display 'last number))
-
-;;;###autoload
-(defun guix-system-generations-by-time (from to)
-  "Display information about system generations created between FROM and TO."
-  (interactive
-   (list (guix-read-date "Find generations (from): ")
-         (guix-read-date "Find generations (to): ")))
-  (guix-system-generation-get-display
-   'time (float-time from) (float-time to)))
-
-(provide 'guix-ui-system-generation)
-
-;;; guix-ui-system-generation.el ends here
diff --git a/emacs/guix-ui.el b/emacs/guix-ui.el
deleted file mode 100644
index 1b69631..0000000
--- a/emacs/guix-ui.el
+++ /dev/null
@@ -1,323 +0,0 @@
-;;; guix-ui.el --- Common code for Guix package management interface  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides some general code for 'list'/'info' interfaces for
-;; packages and generations.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'guix-backend)
-(require 'guix-buffer)
-(require 'guix-guile)
-(require 'guix-utils)
-(require 'guix-messages)
-(require 'guix-profiles)
-
-(guix-define-groups ui
-  :group-doc "\
-Settings for 'ui' (Guix package management) buffers.
-This group includes settings for displaying packages, outputs and
-generations in 'list' and 'info' buffers.")
-
-(defvar guix-ui-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M") 'guix-apply-manifest)
-    (define-key map (kbd "C-c C-z") 'guix-switch-to-repl)
-    map)
-  "Parent keymap for Guix package/generation buffers.")
-
-(guix-buffer-define-current-args-accessors
- "guix-ui-current" "profile" "search-type" "search-values")
-
-(defun guix-ui-read-profile ()
-  "Return `guix-current-profile' or prompt for it.
-This function is intended for using in `interactive' forms."
-  (if current-prefix-arg
-      (guix-profile-prompt)
-    guix-current-profile))
-
-(defun guix-ui-get-entries (profile entry-type search-type search-values
-                                    &optional params)
-  "Receive ENTRY-TYPE entries for PROFILE.
-Call an appropriate scheme procedure and return a list of entries.
-
-ENTRY-TYPE should be one of the following symbols: `package',
-`output' or `generation'.
-
-SEARCH-TYPE may be one of the following symbols:
-
-- If ENTRY-TYPE is `package' or `output': `id', `name', `regexp',
-  `all-available', `newest-available', `installed', `obsolete',
-  `generation'.
-
-- If ENTRY-TYPE is `generation': `id', `last', `all', `time'.
-
-PARAMS is a list of parameters for receiving.  If nil, get data
-with all available parameters."
-  (guix-eval-read
-   (guix-make-guile-expression
-    'entries
-    profile params entry-type search-type search-values)))
-
-(defun guix-ui-list-describe (ids)
-  "Describe 'ui' entries with IDS (list of identifiers)."
-  (guix-buffer-get-display-entries
-   'info (guix-buffer-current-entry-type)
-   (cl-list* (guix-ui-current-profile) 'id ids)
-   'add))
-
-\f
-;;; Buffers and auto updating
-
-(defcustom guix-ui-update-after-operation 'current
-  "Define what kind of data to update after executing an operation.
-
-After successful executing an operation in the Guix REPL (for
-example after installing a package), the data in Guix buffers
-will or will not be automatically updated depending on a value of
-this variable.
-
-If nil, update nothing (do not revert any buffer).
-If `current', update the buffer from which an operation was performed.
-If `all', update all Guix buffers (not recommended)."
-  :type '(choice (const :tag "Do nothing" nil)
-                 (const :tag "Update operation buffer" current)
-                 (const :tag "Update all Guix buffers" all))
-  :group 'guix-ui)
-
-(defcustom guix-ui-buffer-name-function
-  #'guix-ui-buffer-name-full
-  "Function used to define a name of a Guix buffer.
-The function is called with 2 arguments: BASE-NAME and PROFILE."
-  :type '(choice (function-item guix-ui-buffer-name-full)
-                 (function-item guix-ui-buffer-name-short)
-                 (function-item guix-ui-buffer-name-simple)
-                 (function :tag "Other function"))
-  :group 'guix-ui)
-
-(defun guix-ui-buffer-name-simple (base-name &rest _)
-  "Return BASE-NAME."
-  base-name)
-
-(defun guix-ui-buffer-name-short (base-name profile)
-  "Return buffer name by appending BASE-NAME and PROFILE's base file name."
-  (guix-compose-buffer-name base-name
-                            (file-name-base (directory-file-name profile))))
-
-(defun guix-ui-buffer-name-full (base-name profile)
-  "Return buffer name by appending BASE-NAME and PROFILE's full name."
-  (guix-compose-buffer-name base-name profile))
-
-(defun guix-ui-buffer-name (base-name profile)
-  "Return Guix buffer name based on BASE-NAME and profile.
-See `guix-ui-buffer-name-function' for details."
-  (funcall guix-ui-buffer-name-function
-           base-name profile))
-
-(defun guix-ui-buffer? (&optional buffer modes)
-  "Return non-nil if BUFFER mode is derived from any of the MODES.
-If BUFFER is nil, check current buffer.
-If MODES is nil, use `guix-list-mode' and `guix-info-mode'."
-  (with-current-buffer (or buffer (current-buffer))
-    (apply #'derived-mode-p
-           (or modes '(guix-list-mode guix-info-mode)))))
-
-(defun guix-ui-buffers (&optional modes)
-  "Return a list of all buffers with major modes derived from MODES.
-If MODES is nil, return list of all Guix 'list' and 'info' buffers."
-  (cl-remove-if-not (lambda (buf)
-                      (guix-ui-buffer? buf modes))
-                    (buffer-list)))
-
-(defun guix-ui-update-buffer (buffer)
-  "Update data in a 'list' or 'info' BUFFER."
-  (with-current-buffer buffer
-    (guix-buffer-revert nil t)))
-
-(defun guix-ui-update-buffers-after-operation ()
-  "Update buffers after Guix operation if needed.
-See `guix-ui-update-after-operation' for details."
-  (let ((to-update
-         (and guix-operation-buffer
-              (cl-case guix-ui-update-after-operation
-                (current (and (buffer-live-p guix-operation-buffer)
-                              (guix-ui-buffer? guix-operation-buffer)
-                              (list guix-operation-buffer)))
-                (all     (guix-ui-buffers))))))
-    (setq guix-operation-buffer nil)
-    (mapc #'guix-ui-update-buffer to-update)))
-
-(add-hook 'guix-after-repl-operation-hook
-          'guix-ui-update-buffers-after-operation)
-
-\f
-;;; Interface definers
-
-(defmacro guix-ui-define-entry-type (entry-type &rest args)
-  "Define general code for ENTRY-TYPE.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-The rest keyword arguments are passed to
-`guix-define-entry-type' macro."
-  (declare (indent 1))
-  `(guix-define-entry-type ,entry-type
-     :parent-group guix-ui
-     :parent-faces-group guix-ui-faces
-     ,@args))
-
-(defmacro guix-ui-define-interface (buffer-type entry-type &rest args)
-  "Define BUFFER-TYPE interface for displaying ENTRY-TYPE entries.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-In the following description TYPE means ENTRY-TYPE-BUFFER-TYPE.
-
-Required keywords:
-
-  - `:buffer-name' - base part of a buffer name.  It is used in a
-    generated `guix-TYPE-buffer-name' function; see
-    `guix-ui-buffer-name' for details.
-
-Optional keywords:
-
-  - `:required' - default value of the generated
-    `guix-TYPE-required-params' variable.
-
-The rest keyword arguments are passed to
-`guix-BUFFER-TYPE-define-interface' macro.
-
-Along with the mentioned definitions, this macro also defines:
-
-  - `guix-TYPE-mode-map' - keymap based on `guix-ui-map' and
-    `guix-BUFFER-TYPE-mode-map'.
-
-  - `guix-TYPE-get-entries' - a wrapper around `guix-ui-get-entries'.
-
-  - `guix-TYPE-message' - a wrapper around `guix-result-message'."
-  (declare (indent 2))
-  (let* ((entry-type-str  (symbol-name entry-type))
-         (buffer-type-str (symbol-name buffer-type))
-         (prefix          (concat "guix-" entry-type-str "-"
-                                  buffer-type-str))
-         (mode-str        (concat prefix "-mode"))
-         (mode-map        (intern (concat mode-str "-map")))
-         (parent-map      (intern (format "guix-%s-mode-map"
-                                          buffer-type-str)))
-         (required-var    (intern (concat prefix "-required-params")))
-         (buffer-name-fun (intern (concat prefix "-buffer-name")))
-         (get-fun         (intern (concat prefix "-get-entries")))
-         (message-fun     (intern (concat prefix "-message")))
-         (displayed-fun   (intern (format "guix-%s-displayed-params"
-                                          buffer-type-str)))
-         (definer         (intern (format "guix-%s-define-interface"
-                                          buffer-type-str))))
-    (guix-keyword-args-let args
-        ((buffer-name-val :buffer-name)
-         (required-val    :required ''(id)))
-      `(progn
-         (defvar ,mode-map
-           (let ((map (make-sparse-keymap)))
-             (set-keymap-parent
-              map (make-composed-keymap ,parent-map guix-ui-map))
-             map)
-           ,(format "Keymap for `%s' buffers." mode-str))
-
-         (defvar ,required-var ,required-val
-           ,(format "\
-List of the required '%s' parameters.
-These parameters are received by `%S'
-along with the displayed parameters.
-
-Do not remove `id' from this list as it is required for
-identifying an entry."
-                    entry-type-str get-fun))
-
-         (defun ,buffer-name-fun (profile &rest _)
-           ,(format "\
-Return a name of '%s' buffer for displaying '%s' entries.
-See `guix-ui-buffer-name' for details."
-                    buffer-type-str entry-type-str)
-           (guix-ui-buffer-name ,buffer-name-val profile))
-
-         (defun ,get-fun (profile search-type &rest search-values)
-           ,(format "\
-Receive '%s' entries for displaying them in '%s' buffer.
-See `guix-ui-get-entries' for details."
-                    entry-type-str buffer-type-str)
-           (guix-ui-get-entries
-            profile ',entry-type search-type search-values
-            (cl-union ,required-var
-                      (,displayed-fun ',entry-type))))
-
-         (defun ,message-fun (entries profile search-type
-                                      &rest search-values)
-           ,(format "\
-Display a message after showing '%s' entries."
-                    entry-type-str)
-           (guix-result-message
-            profile entries ',entry-type search-type search-values))
-
-         (,definer ,entry-type
-           :get-entries-function ',get-fun
-           :message-function ',message-fun
-           :buffer-name ',buffer-name-fun
-           ,@%foreign-args)))))
-
-(defmacro guix-ui-info-define-interface (entry-type &rest args)
-  "Define 'info' interface for displaying ENTRY-TYPE entries.
-See `guix-ui-define-interface'."
-  (declare (indent 1))
-  `(guix-ui-define-interface info ,entry-type
-     ,@args))
-
-(defmacro guix-ui-list-define-interface (entry-type &rest args)
-  "Define 'list' interface for displaying ENTRY-TYPE entries.
-Remaining arguments (ARGS) should have a form [KEYWORD VALUE] ...
-
-Optional keywords:
-
-  - `:describe-function' - default value of the generated
-    `guix-ENTRY-TYPE-list-describe-function' variable (if not
-    specified, use `guix-ui-list-describe').
-
-The rest keyword arguments are passed to
-`guix-ui-define-interface' macro."
-  (declare (indent 1))
-  (guix-keyword-args-let args
-      ((describe-val :describe-function))
-    `(guix-ui-define-interface list ,entry-type
-       :describe-function ,(or describe-val ''guix-ui-list-describe)
-       ,@args)))
-
-\f
-(defvar guix-ui-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group (or "guix-ui-define-entry-type"
-                           "guix-ui-define-interface"
-                           "guix-ui-info-define-interface"
-                           "guix-ui-list-define-interface"))
-            symbol-end)
-       . 1))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-ui-font-lock-keywords)
-
-(provide 'guix-ui)
-
-;;; guix-ui.el ends here
diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el
deleted file mode 100644
index 3e4ecc3..0000000
--- a/emacs/guix-utils.el
+++ /dev/null
@@ -1,609 +0,0 @@
-;;; guix-utils.el --- General utility functions  -*- lexical-binding: t -*-
-
-;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides auxiliary general functions for guix.el package.
-
-;;; Code:
-
-(require 'cl-lib)
-
-(defvar guix-true-string "Yes")
-(defvar guix-false-string "–")
-(defvar guix-list-separator ", ")
-
-(defvar guix-time-format "%F %T"
-  "String used to format time values.
-For possible formats, see `format-time-string'.")
-
-(defun guix-get-string (val &optional face)
-  "Convert VAL into a string and return it.
-
-VAL can be an expression of any type.
-If VAL is t/nil, it is replaced with
-`guix-true-string'/`guix-false-string'.
-If VAL is list, its elements are concatenated using
-`guix-list-separator'.
-
-If FACE is non-nil, propertize returned string with this FACE."
-  (let ((str (cond
-              ((stringp val) val)
-              ((null val) guix-false-string)
-              ((eq t val) guix-true-string)
-              ((numberp val) (number-to-string val))
-              ((listp val) (mapconcat #'guix-get-string
-                                      val guix-list-separator))
-              (t (prin1-to-string val)))))
-    (if (and val face)
-        (propertize str 'font-lock-face face)
-      str)))
-
-(defun guix-get-time-string (seconds)
-  "Return formatted time string from SECONDS.
-Use `guix-time-format'."
-  (format-time-string guix-time-format (seconds-to-time seconds)))
-
-(defun guix-get-one-line (str)
-  "Return one-line string from a multi-line STR."
-  (replace-regexp-in-string "\n" " " str))
-
-(defmacro guix-with-indent (indent &rest body)
-  "Evaluate BODY and indent inserted text by INDENT number of spaces."
-  (declare (indent 1) (debug t))
-  (let ((region-beg-var (make-symbol "region-beg"))
-        (indent-var     (make-symbol "indent")))
-    `(let ((,region-beg-var (point))
-           (,indent-var     ,indent))
-       ,@body
-       (unless (zerop ,indent-var)
-         (indent-rigidly ,region-beg-var (point) ,indent-var)))))
-
-(defun guix-format-insert (val &optional face format)
-  "Convert VAL into a string and insert it at point.
-If FACE is non-nil, propertize VAL with FACE.
-If FORMAT is non-nil, format VAL with FORMAT."
-  (let ((str (guix-get-string val face)))
-    (insert (if format
-                (format format str)
-              str))))
-
-(cl-defun guix-mapinsert (function sequence separator &key indent column)
-  "Like `mapconcat' but for inserting text.
-Apply FUNCTION to each element of SEQUENCE, and insert SEPARATOR
-at point between each FUNCTION call.
-
-If INDENT is non-nil, it should be a number of spaces used to
-indent each line of the inserted text.
-
-If COLUMN is non-nil, it should be a column number which
-shouldn't be exceeded by the inserted text."
-  (pcase sequence
-    (`(,first . ,rest)
-     (let* ((indent (or indent 0))
-            (max-column (and column (- column indent))))
-       (guix-with-indent indent
-         (funcall function first)
-         (dolist (element rest)
-           (let ((before-sep-pos (and column (point))))
-             (insert separator)
-             (let ((after-sep-pos (and column (point))))
-               (funcall function element)
-               (when (and column
-                          (> (current-column) max-column))
-                 (save-excursion
-                   (delete-region before-sep-pos after-sep-pos)
-                   (goto-char before-sep-pos)
-                   (insert "\n")))))))))))
-
-(defun guix-insert-button (label &optional type &rest properties)
-  "Make button of TYPE with LABEL and insert it at point.
-See `insert-text-button' for the meaning of PROPERTIES."
-  (if (null label)
-      (guix-format-insert nil)
-    (apply #'insert-text-button label
-           :type (or type 'button)
-           properties)))
-
-(defun guix-buttonize (value button-type separator &rest properties)
-  "Make BUTTON-TYPE button(s) from VALUE.
-Return a string with button(s).
-
-VALUE should be a string or a list of strings.  If it is a list
-of strings, buttons are separated with SEPARATOR string.
-
-PROPERTIES are passed to `guix-insert-button'."
-  (with-temp-buffer
-    (let ((labels (if (listp value) value (list value))))
-      (guix-mapinsert (lambda (label)
-                        (apply #'guix-insert-button
-                               label button-type properties))
-                      labels
-                      separator))
-    (buffer-substring (point-min) (point-max))))
-
-(defun guix-button-type? (symbol)
-  "Return non-nil, if SYMBOL is a button type."
-  (and symbol
-       (get symbol 'button-category-symbol)))
-
-(defun guix-split-insert (val &optional face col separator)
-  "Convert VAL into a string, split it and insert at point.
-
-If FACE is non-nil, propertize returned string with this FACE.
-
-If COL is non-nil and result string is a one-line string longer
-than COL, split it into several short lines.
-
-Separate inserted lines with SEPARATOR."
-  (if (null val)
-      (guix-format-insert nil)
-    (let ((strings (guix-split-string (guix-get-string val) col)))
-      (guix-mapinsert (lambda (str) (guix-format-insert str face))
-                      strings
-                      (or separator "")))))
-
-(defun guix-split-string (str &optional col)
-  "Split string STR by lines and return list of result strings.
-If COL is non-nil, fill STR to this column."
-  (let ((str (if col
-                 (guix-get-filled-string str col)
-               str)))
-    (split-string str "\n *" t)))
-
-(defun guix-get-filled-string (str col)
-  "Return string by filling STR to column COL."
-  (with-temp-buffer
-    (insert str)
-    (let ((fill-column col))
-      (fill-region (point-min) (point-max)))
-    (buffer-string)))
-
-(defun guix-concat-strings (strings separator &optional location)
-  "Return new string by concatenating STRINGS with SEPARATOR.
-If LOCATION is a symbol `head', add another SEPARATOR to the
-beginning of the returned string; if `tail' - add SEPARATOR to
-the end of the string; if nil, do not add SEPARATOR; otherwise
-add both to the end and to the beginning."
-  (let ((str (mapconcat #'identity strings separator)))
-    (cond ((null location)
-           str)
-          ((eq location 'head)
-           (concat separator str))
-          ((eq location 'tail)
-           (concat str separator))
-          (t
-           (concat separator str separator)))))
-
-(defun guix-hexify (value)
-  "Convert VALUE to string and hexify it."
-  (url-hexify-string (guix-get-string value)))
-
-(defun guix-number->bool (number)
-  "Convert NUMBER to boolean value.
-Return nil, if NUMBER is 0; return t otherwise."
-  (not (zerop number)))
-
-(defun guix-shell-quote-argument (argument)
-  "Quote shell command ARGUMENT.
-This function is similar to `shell-quote-argument', but less strict."
-  (if (equal argument "")
-      "''"
-    (replace-regexp-in-string
-     "\n" "'\n'"
-     (replace-regexp-in-string
-      (rx (not (any alnum "-=,./\n"))) "\\\\\\&" argument))))
-
-(defun guix-symbol-title (symbol)
-  "Return SYMBOL's name, a string.
-This is like `symbol-name', but fancier."
-  (if (eq symbol 'id)
-      "ID"
-    (let ((str (replace-regexp-in-string "-" " " (symbol-name symbol))))
-      (concat (capitalize (substring str 0 1))
-              (substring str 1)))))
-
-(defun guix-command-symbol (&optional args)
-  "Return symbol by concatenating 'guix' and ARGS (strings)."
-  (intern (guix-concat-strings (cons "guix" args) "-")))
-
-(defun guix-command-string (&optional args)
-  "Return 'guix ARGS ...' string with quoted shell arguments."
-  (let ((args (mapcar #'guix-shell-quote-argument args)))
-    (guix-concat-strings (cons "guix" args) " ")))
-
-(defun guix-copy-as-kill (string &optional no-message?)
-  "Put STRING into `kill-ring'.
-If NO-MESSAGE? is non-nil, do not display a message about it."
-  (kill-new string)
-  (unless no-message?
-    (message "'%s' has been added to kill ring." string)))
-
-(defun guix-copy-command-as-kill (args &optional no-message?)
-  "Put 'guix ARGS ...' string into `kill-ring'.
-See also `guix-copy-as-kill'."
-  (guix-copy-as-kill (guix-command-string args) no-message?))
-
-(defun guix-compose-buffer-name (base-name postfix)
-  "Return buffer name by appending BASE-NAME and POSTFIX.
-
-In a simple case the result is:
-
-  BASE-NAME: POSTFIX
-
-If BASE-NAME is wrapped by '*', then the result is:
-
-  *BASE-NAME: POSTFIX*"
-  (let ((re (rx string-start
-                (group (? "*"))
-                (group (*? any))
-                (group (? "*"))
-                string-end)))
-    (or (string-match re base-name)
-        (error "Unexpected error in defining buffer name"))
-    (let ((first*    (match-string 1 base-name))
-          (name-body (match-string 2 base-name))
-          (last*     (match-string 3 base-name)))
-      ;; Handle the case when buffer name is wrapped by '*'.
-      (if (and (string= "*" first*)
-               (string= "*" last*))
-          (concat "*" name-body ": " postfix "*")
-        (concat base-name ": " postfix)))))
-
-(defun guix-completing-read (prompt table &optional predicate
-                             require-match initial-input
-                             hist def inherit-input-method)
-  "Same as `completing-read' but return nil instead of an empty string."
-  (let ((res (completing-read prompt table predicate
-                              require-match initial-input
-                              hist def inherit-input-method)))
-    (unless (string= "" res) res)))
-
-(defun guix-completing-read-multiple (prompt table &optional predicate
-                                      require-match initial-input
-                                      hist def inherit-input-method)
-  "Same as `completing-read-multiple' but remove duplicates in result."
-  (cl-remove-duplicates
-   (completing-read-multiple prompt table predicate
-                             require-match initial-input
-                             hist def inherit-input-method)
-   :test #'string=))
-
-(declare-function org-read-date "org" t)
-
-(defun guix-read-date (prompt)
-  "Prompt for a date or time using `org-read-date'.
-Return time value."
-  (require 'org)
-  (org-read-date nil t nil prompt))
-
-(defun guix-read-file-name (prompt &optional dir default-filename
-                                   mustmatch initial predicate)
-  "Read file name.
-This function is similar to `read-file-name' except it also
-expands the file name."
-  (expand-file-name (read-file-name prompt dir default-filename
-                                    mustmatch initial predicate)))
-
-(defcustom guix-find-file-function #'find-file
-  "Function used to find a file.
-The function is called by `guix-find-file' with a file name as a
-single argument."
-  :type '(choice (function-item find-file)
-                 (function-item org-open-file)
-                 (function :tag "Other function"))
-  :group 'guix)
-
-(defun guix-find-file (file)
-  "Find FILE if it exists."
-  (if (file-exists-p file)
-      (funcall guix-find-file-function file)
-    (message "File '%s' does not exist." file)))
-
-(defvar url-handler-regexp)
-
-(defun guix-find-file-or-url (file-or-url)
-  "Find FILE-OR-URL."
-  (require 'url-handlers)
-  (let ((file-name-handler-alist
-         (cons (cons url-handler-regexp 'url-file-handler)
-               file-name-handler-alist)))
-    (find-file file-or-url)))
-
-(defmacro guix-while-search (regexp &rest body)
-  "Evaluate BODY after each search for REGEXP in the current buffer."
-  (declare (indent 1) (debug t))
-  `(save-excursion
-     (goto-char (point-min))
-     (while (re-search-forward ,regexp nil t)
-       ,@body)))
-
-(defmacro guix-while-null (&rest body)
-  "Evaluate BODY until its result becomes non-nil."
-  (declare (indent 0) (debug t))
-  (let ((result-var (make-symbol "result")))
-    `(let (,result-var)
-       (while (null ,result-var)
-         (setq ,result-var ,@body))
-       ,result-var)))
-
-(defun guix-modify (object modifiers)
-  "Apply MODIFIERS to OBJECT.
-OBJECT is passed as an argument to the first function from
-MODIFIERS list, the returned result is passed to the second
-function from the list and so on.  Return result of the last
-modifier call."
-  (if (null modifiers)
-      object
-    (guix-modify (funcall (car modifiers) object)
-                 (cdr modifiers))))
-
-(defmacro guix-keyword-args-let (args varlist &rest body)
-  "Parse ARGS, bind variables from VARLIST and eval BODY.
-
-Find keyword values in ARGS, bind them to variables according to
-VARLIST, then evaluate BODY.
-
-ARGS is a keyword/value property list.
-
-Each element of VARLIST has a form:
-
-  (SYMBOL KEYWORD [DEFAULT-VALUE])
-
-SYMBOL is a varible name.  KEYWORD is a symbol that will be
-searched in ARGS for an according value.  If the value of KEYWORD
-does not exist, bind SYMBOL to DEFAULT-VALUE or nil.
-
-The rest arguments (that present in ARGS but not in VARLIST) will
-be bound to `%foreign-args' variable.
-
-Example:
-
-  (guix-keyword-args-let '(:two 8 :great ! :guix is)
-      ((one :one 1)
-       (two :two 2)
-       (foo :smth))
-    (list one two foo %foreign-args))
-
-  => (1 8 nil (:guix is :great !))"
-  (declare (indent 2))
-  (let ((args-var (make-symbol "args")))
-    `(let (,@(mapcar (lambda (spec)
-                       (pcase-let ((`(,name ,_ ,val) spec))
-                         (list name val)))
-                     varlist)
-           (,args-var ,args)
-           %foreign-args)
-       (while ,args-var
-         (pcase ,args-var
-           (`(,key ,val . ,rest-args)
-            (cl-case key
-              ,@(mapcar (lambda (spec)
-                          (pcase-let ((`(,name ,key ,_) spec))
-                            `(,key (setq ,name val))))
-                        varlist)
-              (t (setq %foreign-args
-                       (cl-list* key val %foreign-args))))
-            (setq ,args-var rest-args))))
-       ,@body)))
-
-\f
-;;; Alist procedures
-
-(defmacro guix-define-alist-accessor (name assoc-fun)
-  "Define NAME function to access alist values using ASSOC-FUN."
-  `(defun ,name (alist &rest keys)
-     ,(format "Return value from ALIST by KEYS using `%s'.
-ALIST is alist of alists of alists ... which can be consecutively
-accessed with KEYS."
-              assoc-fun)
-     (if (or (null alist) (null keys))
-         alist
-       (apply #',name
-              (cdr (,assoc-fun (car keys) alist))
-              (cdr keys)))))
-
-(guix-define-alist-accessor guix-assq-value assq)
-(guix-define-alist-accessor guix-assoc-value assoc)
-
-(defun guix-alist-put (value alist &rest keys)
-  "Put (add or replace if exists) VALUE to ALIST using KEYS.
-Return the new alist.
-
-ALIST is alist of alists of alists ... which can be consecutively
-accessed with KEYS.
-
-Example:
-
-  (guix-alist-put
-   'foo
-   '((one (a . 1) (b . 2))
-     (two (m . 7) (n . 8)))
-   'one 'b)
-
-  => ((one (a . 1) (b . foo))
-      (two (m . 7) (n . 8)))"
-  (or keys (error "Keys should be specified"))
-  (guix-alist-put-1 value alist keys))
-
-(defun guix-alist-put-1 (value alist keys)
-  "Subroutine of `guix-alist-put'."
-  (cond
-   ((null keys)
-    value)
-   ((null alist)
-    (list (cons (car keys)
-                (guix-alist-put-1 value nil (cdr keys)))))
-   ((eq (car keys) (caar alist))
-    (cons (cons (car keys)
-                (guix-alist-put-1 value (cdar alist) (cdr keys)))
-          (cdr alist)))
-   (t
-    (cons (car alist)
-          (guix-alist-put-1 value (cdr alist) keys)))))
-
-(defun guix-alist-put! (value variable &rest keys)
-  "Modify alist VARIABLE (symbol) by putting VALUE using KEYS.
-See `guix-alist-put' for details."
-  (set variable
-       (apply #'guix-alist-put value (symbol-value variable) keys)))
-
-\f
-;;; Diff
-
-(defvar guix-diff-switches "-u"
-  "A string or list of strings specifying switches to be passed to diff.")
-
-(defun guix-diff (old new &optional switches no-async)
-  "Same as `diff', but use `guix-diff-switches' as default."
-  (diff old new (or switches guix-diff-switches) no-async))
-
-\f
-;;; Completing readers definers
-
-(defmacro guix-define-reader (name read-fun completions prompt)
-  "Define NAME function to read from minibuffer.
-READ-FUN may be `completing-read', `completing-read-multiple' or
-another function with the same arguments."
-  `(defun ,name (&optional prompt initial-contents)
-     (,read-fun ,(if prompt
-                     `(or prompt ,prompt)
-                   'prompt)
-                ,completions nil nil initial-contents)))
-
-(defmacro guix-define-readers (&rest args)
-  "Define reader functions.
-
-ARGS should have a form [KEYWORD VALUE] ...  The following
-keywords are available:
-
-  - `completions-var' - variable used to get completions.
-
-  - `completions-getter' - function used to get completions.
-
-  - `single-reader', `single-prompt' - name of a function to read
-    a single value, and a prompt for it.
-
-  - `multiple-reader', `multiple-prompt' - name of a function to
-    read multiple values, and a prompt for it.
-
-  - `multiple-separator' - if specified, another
-    `<multiple-reader-name>-string' function returning a string
-    of multiple values separated the specified separator will be
-    defined."
-  (guix-keyword-args-let args
-      ((completions-var    :completions-var)
-       (completions-getter :completions-getter)
-       (single-reader      :single-reader)
-       (single-prompt      :single-prompt)
-       (multiple-reader    :multiple-reader)
-       (multiple-prompt    :multiple-prompt)
-       (multiple-separator :multiple-separator))
-    (let ((completions
-           (cond ((and completions-var completions-getter)
-                  `(or ,completions-var
-                       (setq ,completions-var
-                             (funcall ',completions-getter))))
-                 (completions-var
-                  completions-var)
-                 (completions-getter
-                  `(funcall ',completions-getter)))))
-      `(progn
-         ,(when (and completions-var
-                     (not (boundp completions-var)))
-            `(defvar ,completions-var nil))
-
-         ,(when single-reader
-            `(guix-define-reader ,single-reader guix-completing-read
-                                 ,completions ,single-prompt))
-
-         ,(when multiple-reader
-            `(guix-define-reader ,multiple-reader completing-read-multiple
-                                 ,completions ,multiple-prompt))
-
-         ,(when (and multiple-reader multiple-separator)
-            (let ((name (intern (concat (symbol-name multiple-reader)
-                                        "-string"))))
-              `(defun ,name (&optional prompt initial-contents)
-                 (guix-concat-strings
-                  (,multiple-reader prompt initial-contents)
-                  ,multiple-separator))))))))
-
-\f
-;;; Memoizing
-
-(defun guix-memoize (function)
-  "Return a memoized version of FUNCTION."
-  (let ((cache (make-hash-table :test 'equal)))
-    (lambda (&rest args)
-      (let ((result (gethash args cache 'not-found)))
-        (if (eq result 'not-found)
-            (let ((result (apply function args)))
-              (puthash args result cache)
-              result)
-          result)))))
-
-(defmacro guix-memoized-defun (name arglist docstring &rest body)
-  "Define a memoized function NAME.
-See `defun' for the meaning of arguments."
-  (declare (doc-string 3) (indent 2))
-  `(defalias ',name
-     (guix-memoize (lambda ,arglist ,@body))
-     ;; Add '(name args ...)' string with real arglist to the docstring,
-     ;; because *Help* will display '(name &rest ARGS)' for a defined
-     ;; function (since `guix-memoize' returns a lambda with '(&rest
-     ;; args)').
-     ,(format "(%S %s)\n\n%s"
-              name
-              (mapconcat #'symbol-name arglist " ")
-              docstring)))
-
-(defmacro guix-memoized-defalias (symbol definition &optional docstring)
-  "Set SYMBOL's function definition to memoized version of DEFINITION."
-  (declare (doc-string 3) (indent 1))
-  `(defalias ',symbol
-     (guix-memoize #',definition)
-     ,(or docstring
-          (format "Memoized version of `%S'." definition))))
-
-\f
-(defvar guix-utils-font-lock-keywords
-  (eval-when-compile
-    `((,(rx "(" (group (or "guix-define-reader"
-                           "guix-define-readers"
-                           "guix-keyword-args-let"
-                           "guix-while-null"
-                           "guix-while-search"
-                           "guix-with-indent"))
-            symbol-end)
-       . 1)
-      (,(rx "("
-            (group "guix-memoized-" (or "defun" "defalias"))
-            symbol-end
-            (zero-or-more blank)
-            (zero-or-one
-             (group (one-or-more (or (syntax word) (syntax symbol))))))
-       (1 font-lock-keyword-face)
-       (2 font-lock-function-name-face nil t)))))
-
-(font-lock-add-keywords 'emacs-lisp-mode guix-utils-font-lock-keywords)
-
-(provide 'guix-utils)
-
-;;; guix-utils.el ends here
diff --git a/emacs/local.mk b/emacs/local.mk
deleted file mode 100644
index 959ec2d..0000000
--- a/emacs/local.mk
+++ /dev/null
@@ -1,77 +0,0 @@
-# GNU Guix --- Functional package management for GNU
-# Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
-# Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
-#
-# This file is part of GNU Guix.
-#
-# GNU Guix is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or (at
-# your option) any later version.
-#
-# GNU Guix is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
-
-AUTOLOADS = %D%/guix-autoloads.el
-
-ELFILES =					\
-  %D%/guix-about.el				\
-  %D%/guix-backend.el				\
-  %D%/guix-base.el				\
-  %D%/guix-build-log.el				\
-  %D%/guix-buffer.el				\
-  %D%/guix-command.el				\
-  %D%/guix-devel.el				\
-  %D%/guix-emacs.el				\
-  %D%/guix-entry.el				\
-  %D%/guix-external.el				\
-  %D%/guix-geiser.el				\
-  %D%/guix-guile.el				\
-  %D%/guix-help-vars.el				\
-  %D%/guix-history.el				\
-  %D%/guix-hydra.el				\
-  %D%/guix-hydra-build.el			\
-  %D%/guix-hydra-jobset.el			\
-  %D%/guix-info.el				\
-  %D%/guix-init.el				\
-  %D%/guix-license.el				\
-  %D%/guix-list.el				\
-  %D%/guix-location.el				\
-  %D%/guix-messages.el				\
-  %D%/guix-pcomplete.el				\
-  %D%/guix-popup.el				\
-  %D%/guix-prettify.el				\
-  %D%/guix-profiles.el				\
-  %D%/guix-read.el				\
-  %D%/guix-ui.el				\
-  %D%/guix-ui-license.el			\
-  %D%/guix-ui-location.el			\
-  %D%/guix-ui-package.el			\
-  %D%/guix-ui-generation.el			\
-  %D%/guix-ui-system-generation.el		\
-  %D%/guix-utils.el
-
-if HAVE_EMACS
-
-dist_lisp_DATA = $(ELFILES)
-
-nodist_lisp_DATA = 		\
-  %D%/guix-config.el		\
-  $(AUTOLOADS)
-
-$(AUTOLOADS): $(ELFILES)
-	$(AM_V_EMACS)$(EMACS) --batch --eval				\
-	  "(let ((backup-inhibited t)					\
-	         (generated-autoload-file				\
-	          (expand-file-name \"$(AUTOLOADS)\" \"$(builddir)\")))	\
-	     (update-directory-autoloads				\
-	      (expand-file-name \"emacs\" \"$(srcdir)\")))"
-
-CLEANFILES += $(AUTOLOADS)
-
-endif HAVE_EMACS
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index 732dbc2..1b9191c 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -44,7 +44,6 @@
   #:use-module (gnu packages curl)
   #:use-module (gnu packages web)
   #:use-module (gnu packages man)
-  #:use-module (gnu packages emacs)
   #:use-module (gnu packages bdw-gc)
   #:use-module (gnu packages python)
   #:use-module (gnu packages popt)
@@ -162,7 +161,6 @@
 
                        #t))))))
     (native-inputs `(("pkg-config" ,pkg-config)
-                     ("emacs" ,emacs-minimal)     ;for guix.el
 
                      ;; XXX: Keep the development inputs here even though
                      ;; they're unnecessary, just so that 'guix environment
@@ -206,9 +204,7 @@
     (propagated-inputs
      `(("gnutls" ,gnutls)                         ;for 'guix download' & co.
        ("guile-json" ,guile-json)
-       ("guile-ssh" ,guile-ssh)
-       ("geiser" ,geiser)                         ;for guix.el
-       ("emacs-magit-popup" ,emacs-magit-popup))) ;for "M-x guix" command
+       ("guile-ssh" ,guile-ssh)))
 
     (home-page "http://www.gnu.org/software/guix")
     (synopsis "Functional package manager for installed software packages and versions")
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-22  9:15     ` Alex Kost
@ 2016-12-22 15:25       ` myglc2
  0 siblings, 0 replies; 30+ messages in thread
From: myglc2 @ 2016-12-22 15:25 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

On 12/22/2016 at 12:15 Alex Kost writes:

> myglc2 (2016-12-21 19:18 -0500) wrote:
>
>> Have you decided re feedback/support? github issues? mailing list?
>
> Whatever seems appropriate to you: issues or pull requests on
> github/notabug, or mailing me directly is OK.  As for using guix-devel
> mailing list, I think it's not a suitable place, I would like to avoid
> polluting this list with Emacs-Guix stuff.

I think you should provide guidance about this in your README.  A
designated mailing list would be good because it will provide an archive
of questions and answers.

I think you should reconsider "polluting this list" and I think you
should continue using the Guix lists if Ludo and others are
agreeable. My reasoning is as follows:

- 99.9% of your users are on these lists

- emacs-guix remains an essential a part of Guix

- from a user's point of view, its being in a separate repo is a purely
  technical detail

>> Many thanks for continuing to make emacs-guix cooler and cooler!
>
> Thanks, make sure to check "M-x guix-help", if you have not yet.

I did, very cool.

> BTW I'm going to release 0.2.1 in a few days.  It will have "M-x
> guix-about" command, which is not very useful but it's
> "fancy"... well, I'll make an announcement about it :-)

Looking forward ;-)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-18 10:32     ` Ludovic Courtès
  2016-12-18 15:47       ` Adonay Felipe Nogueira
  2016-12-19 21:47       ` Emacs-Guix released outside from Guix Alex Kost
@ 2016-12-22 19:09       ` myglc2
  2 siblings, 0 replies; 30+ messages in thread
From: myglc2 @ 2016-12-22 19:09 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel, Alex Kost

On 12/18/2016 at 11:32 Ludovic Courtès writes:

> Hi Alex,
>
> Alex Kost <alezost@gmail.com> skribis:
>
>> Ludovic Courtès (2016-12-15 18:39 +0100) wrote:
>>
[...]
>
>> I always feel uncomfortable to send patches or to push commits to the
>> Guix repo.  I can't explain it properly, it's just painful all the
>> time; but more importantly, it slowed down the development, as I often
>> decided not to do small changes.  Contrary, I made more commits to the
>> Emacs-Guix source tree in the past month, than to the Guix repo during
>> the whole year.
>
> I have the same questions as John: what is it that made you feel
> uncomfortable?  I stated clearly multiple times that you are effectively
> “sudoer” on this code.
>
> Let’s reflect on this for all the future Alexes that come around.  If
> you are in my position, what do you do to make it so that the next Alex
> feels comfortable and happy with this workflow?  What does it take to
> avoid an “Alexit”?  :-)
>
> That’s an honest question: I cannot state what I did wrong, but I’d like
> to learn so it doesn’t happen again.

Hi Ludo’, 

I really don't see the downside to emacs-guix being moved out of the
guix repo.  From the user's point of view, it doesn't matter where the
code lives, as long as it continues to be expertly developed for the
benefit of guix users.

It is true that emacs-guix code changes will no longer pass thru the
guix QC and review process, but you control which emacs-guix code
"ships" with guix via the package definition. So there is no loss of
control.

If an approach like this provides a more comfortable and productive
working environment for a contributor, it seems like a win-win for Guix
users.  Maybe there are other situations where this approach could
address developer issues.

In the case of emacs-guix, which is so closely bound to Guix, I suggest
that you make it a "guix endorsed package."  This would clarify the
situation for guix users. In practice, one thing this could mean would
be for you to host guix-emacs discussion on guix mailing lists, if Alex
is so inclined.

Best, - George

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] Remove Emacs interface.
  2016-12-22 10:35 ` [PATCH] Remove Emacs interface Alex Kost
@ 2016-12-29 17:40   ` Ludovic Courtès
  2016-12-29 20:43     ` Alex Kost
  0 siblings, 1 reply; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-29 17:40 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 480 bytes --]

Hi!

Alex Kost <alezost@gmail.com> skribis:

> The attached patch removes Emacs UI and its documentation (12000 lines
> removed, hooray!).  I added the only mention about 'emacs-guix' package
> in "Package Management" chapter.

OK!

I was thinking that, even if the Emacs-Guix manual isn’t available
online currently, this change would lead users following the link in the
HTML manual to the Emacs-Guix home page (with a wrong anchor), which is
better than 404:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 414 bytes --]

diff --git a/doc/htmlxref.cnf b/doc/htmlxref.cnf
index bd2eb5f..999edfe 100644
--- a/doc/htmlxref.cnf
+++ b/doc/htmlxref.cnf
@@ -219,6 +219,8 @@ emacs		node	${EMACS}/html_node/emacs/
 easejs		mono	${GS}/easejs/manual/easejs.html
 easejs		node	${GS}/easejs/manual/
 
+emacs-guix	mono	https://notabug.org/...
+
 emacs-muse	node	${GS}/emacs-muse/manual/muse.html
 emacs-muse	node	${GS}/emacs-muse/manual/html_node/
 

[-- Attachment #3: Type: text/plain, Size: 1386 bytes --]


Feel free to add it to the patch!

> Now 'emacs' directory contains a single git-controlled file -
> "guix-emacs.el".  It is used to patch our 'emacs' package (to find emacs
> packages in "share/emacs/site-lisp/guix.d").  But it is misplaced.

I agree.  May you can commit this patch first while we look for a
solution?

> What about making "gnu/packages/files" (or another dirname) directory,
> and putting "guix-emacs.el" and kernel configs ("linux-libre-*.conf")
> there?
>
> I mean "gnu/packages/patches" is not always enough, sometimes we want to
> use real files in the package recipes (configs for 'linux-libre' or
> "guix-emacs.el" for 'emacs'), so having "gnu/packages/files" seems
> reasonable to me, WDYT?

Sounds good.

In general, we can create other subdirectories alongside patches/ and
bootstrap/.  So we could have linux-conf/ and emacs/ there.  We can also
add regular files like guix-emacs.el directly under gnu/packages (like
ld-wrapper.in, linux-conf.*, etc.)

All this is fine as long as the files get installed in the right place
wrt. %load-path.

I’m not sure a catch-all files/ (or aux-files/?) directory is helpful
though.  There’s a case for having a linux-conf/ subdirectory now; for
guix-emacs.el, I am slightly inclined to put it directly in
gnu/packages, but no strong opinion.

Thoughts?

Thank you!

Ludo’.

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH] Remove Emacs interface.
  2016-12-29 17:40   ` Ludovic Courtès
@ 2016-12-29 20:43     ` Alex Kost
  2016-12-31 11:34       ` Auxiliary files Ludovic Courtès
  0 siblings, 1 reply; 30+ messages in thread
From: Alex Kost @ 2016-12-29 20:43 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Ludovic Courtès (2016-12-29 18:40 +0100) wrote:

> Hi!
>
> Alex Kost <alezost@gmail.com> skribis:
>
>> The attached patch removes Emacs UI and its documentation (12000 lines
>> removed, hooray!).  I added the only mention about 'emacs-guix' package
>> in "Package Management" chapter.
>
> OK!
>
> I was thinking that, even if the Emacs-Guix manual isn’t available
> online currently, this change would lead users following the link in the
> HTML manual to the Emacs-Guix home page (with a wrong anchor), which is
> better than 404:
>
> diff --git a/doc/htmlxref.cnf b/doc/htmlxref.cnf
> index bd2eb5f..999edfe 100644
> --- a/doc/htmlxref.cnf
> +++ b/doc/htmlxref.cnf
> @@ -219,6 +219,8 @@ emacs		node	${EMACS}/html_node/emacs/
>  easejs		mono	${GS}/easejs/manual/easejs.html
>  easejs		node	${GS}/easejs/manual/
>  
> +emacs-guix	mono	https://notabug.org/...
> +
>  emacs-muse	node	${GS}/emacs-muse/manual/muse.html
>  emacs-muse	node	${GS}/emacs-muse/manual/html_node/
>  
>
> Feel free to add it to the patch!

Added, thanks!

>> Now 'emacs' directory contains a single git-controlled file -
>> "guix-emacs.el".  It is used to patch our 'emacs' package (to find emacs
>> packages in "share/emacs/site-lisp/guix.d").  But it is misplaced.
>
> I agree.  May you can commit this patch first while we look for a
> solution?

Committed.

>> What about making "gnu/packages/files" (or another dirname) directory,
>> and putting "guix-emacs.el" and kernel configs ("linux-libre-*.conf")
>> there?
>>
>> I mean "gnu/packages/patches" is not always enough, sometimes we want to
>> use real files in the package recipes (configs for 'linux-libre' or
>> "guix-emacs.el" for 'emacs'), so having "gnu/packages/files" seems
>> reasonable to me, WDYT?
>
> Sounds good.
>
> In general, we can create other subdirectories alongside patches/ and
> bootstrap/.  So we could have linux-conf/ and emacs/ there.

But we keep all patches in a single directory, why should there be
multiple dirs for auxiliary files?

> We can also
> add regular files like guix-emacs.el directly under gnu/packages (like
> ld-wrapper.in, linux-conf.*, etc.)
>
> All this is fine as long as the files get installed in the right place
> wrt. %load-path.
>
> I’m not sure a catch-all files/ (or aux-files/?) directory is helpful
> though.  There’s a case for having a linux-conf/ subdirectory now; for
> guix-emacs.el, I am slightly inclined to put it directly in
> gnu/packages, but no strong opinion.
>
> Thoughts?

I don't like keeping such files in "gnu/packages" the most!  My opinion
is that only .scm files should be placed there.

I vote either for a single "aux-files" (I like this name) directory, or
for its sub-directories ("aux-files/emacs", "aux-files/linux").

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Auxiliary files
  2016-12-29 20:43     ` Alex Kost
@ 2016-12-31 11:34       ` Ludovic Courtès
  0 siblings, 0 replies; 30+ messages in thread
From: Ludovic Courtès @ 2016-12-31 11:34 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Hi Alex,

Alex Kost <alezost@gmail.com> skribis:

> Ludovic Courtès (2016-12-29 18:40 +0100) wrote:
>
>> Hi!
>>
>> Alex Kost <alezost@gmail.com> skribis:

[...]

>>> What about making "gnu/packages/files" (or another dirname) directory,
>>> and putting "guix-emacs.el" and kernel configs ("linux-libre-*.conf")
>>> there?
>>>
>>> I mean "gnu/packages/patches" is not always enough, sometimes we want to
>>> use real files in the package recipes (configs for 'linux-libre' or
>>> "guix-emacs.el" for 'emacs'), so having "gnu/packages/files" seems
>>> reasonable to me, WDYT?
>>
>> Sounds good.
>>
>> In general, we can create other subdirectories alongside patches/ and
>> bootstrap/.  So we could have linux-conf/ and emacs/ there.
>
> But we keep all patches in a single directory, why should there be
> multiple dirs for auxiliary files?

I imagine linux-conf/ would contain several files (all the configuration
files), and so on.  IOW, we can create directories anytime there’s a
category of files that go together well.  𝅘𝅥𝅮

>> We can also
>> add regular files like guix-emacs.el directly under gnu/packages (like
>> ld-wrapper.in, linux-conf.*, etc.)
>>
>> All this is fine as long as the files get installed in the right place
>> wrt. %load-path.
>>
>> I’m not sure a catch-all files/ (or aux-files/?) directory is helpful
>> though.  There’s a case for having a linux-conf/ subdirectory now; for
>> guix-emacs.el, I am slightly inclined to put it directly in
>> gnu/packages, but no strong opinion.
>>
>> Thoughts?
>
> I don't like keeping such files in "gnu/packages" the most!  My opinion
> is that only .scm files should be placed there.
>
> I vote either for a single "aux-files" (I like this name) directory, or
> for its sub-directories ("aux-files/emacs", "aux-files/linux").

OK, sounds good.  We’ll also need a ‘search-auxiliary-file’ procedure
(or similar) just like we have ‘search-patch’, to facilitate things.

Thanks!

Ludo’.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
                   ` (4 preceding siblings ...)
  2016-12-22 10:35 ` [PATCH] Remove Emacs interface Alex Kost
@ 2017-01-06 15:50 ` Thompson, David
  2017-01-06 21:28   ` Alex Kost
  5 siblings, 1 reply; 30+ messages in thread
From: Thompson, David @ 2017-01-06 15:50 UTC (permalink / raw)
  To: Alex Kost; +Cc: guix-devel

Hey Alex,

On Thu, Dec 15, 2016 at 9:48 AM, Alex Kost <alezost@gmail.com> wrote:
> Hello, I've been working on Emacs interface outside from the Guix repo
> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(

Sorry to hear about this.  This move will make it difficult for me to
use guix.el moving forward due to inevitable API incompatibilities, so
I've decided to just stop using it.  I hope that one day this code
will come back into the guix source tree.

- Dave

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Emacs-Guix released outside from Guix
  2017-01-06 15:50 ` Emacs-Guix released outside from Guix Thompson, David
@ 2017-01-06 21:28   ` Alex Kost
  0 siblings, 0 replies; 30+ messages in thread
From: Alex Kost @ 2017-01-06 21:28 UTC (permalink / raw)
  To: Thompson, David; +Cc: guix-devel

Thompson, David (2017-01-06 10:50 -0500) wrote:

> Hey Alex,
>
> On Thu, Dec 15, 2016 at 9:48 AM, Alex Kost <alezost@gmail.com> wrote:
>> Hello, I've been working on Emacs interface outside from the Guix repo
>> for some time, I mean I'm not going to maintain it inside Guix, sorry :-(
>
> Sorry to hear about this.  This move will make it difficult for me to
> use guix.el moving forward due to inevitable API incompatibilities, so
> I've decided to just stop using it.

As you wish :-)

> I hope that one day this code
> will come back into the guix source tree.

Well, anything can happen, but it's highly unlikely.

-- 
Alex

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2017-01-06 21:28 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-15 14:48 Emacs-Guix released outside from Guix Alex Kost
2016-12-15 14:48 ` [PATCH 1/2] gnu: Add emacs-bui Alex Kost
2016-12-15 17:21   ` Ludovic Courtès
2016-12-15 14:48 ` [PATCH 2/2] gnu: Add emacs-guix Alex Kost
2016-12-15 17:22   ` Ludovic Courtès
2016-12-15 17:39 ` Emacs-Guix released outside from Guix Ludovic Courtès
2016-12-16  0:37   ` Ricardo Wurmus
2016-12-16 16:44     ` Ludovic Courtès
2016-12-17  8:17       ` Alex Kost
2016-12-17  8:38     ` Alex Kost
2016-12-17  9:00       ` John Darrington
2016-12-19 21:38         ` Alex Kost
2016-12-17  8:19   ` Alex Kost
2016-12-18 10:32     ` Ludovic Courtès
2016-12-18 15:47       ` Adonay Felipe Nogueira
2016-12-19  5:00         ` Emacs-Guix released outside from Guix - or why I am not sending patches in Pjotr Prins
2016-12-19 21:47       ` Emacs-Guix released outside from Guix Alex Kost
2016-12-20 13:58         ` Ludovic Courtès
2016-12-22 19:09       ` myglc2
2016-12-18 15:35     ` Pjotr Prins
2016-12-17  9:13 ` Alex Kost
2016-12-22  0:18   ` myglc2
2016-12-22  9:15     ` Alex Kost
2016-12-22 15:25       ` myglc2
2016-12-22 10:35 ` [PATCH] Remove Emacs interface Alex Kost
2016-12-29 17:40   ` Ludovic Courtès
2016-12-29 20:43     ` Alex Kost
2016-12-31 11:34       ` Auxiliary files Ludovic Courtès
2017-01-06 15:50 ` Emacs-Guix released outside from Guix Thompson, David
2017-01-06 21:28   ` Alex Kost

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).