aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi3
-rw-r--r--gnu/machine/ssh.scm31
-rw-r--r--guix/remote.scm14
-rw-r--r--guix/ssh.scm7
4 files changed, 46 insertions, 9 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 734206a4b..a7facf470 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25573,6 +25573,9 @@ with an @code{environment} of @code{managed-host-environment-type}.
@table @asis
@item @code{host-name}
+@item @code{system}
+The Nix system type describing the architecture of the machine being deployed
+to. This should look something like ``x86_64-linux''.
@item @code{port} (default: @code{22})
@item @code{user} (default: @code{"root"})
@item @code{identity} (default: @code{#f})
diff --git a/gnu/machine/ssh.scm b/gnu/machine/ssh.scm
index ba3e33c92..670990a63 100644
--- a/gnu/machine/ssh.scm
+++ b/gnu/machine/ssh.scm
@@ -36,6 +36,7 @@
#:use-module (ice-9 match)
#:use-module (srfi srfi-19)
#:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-34)
#:use-module (srfi srfi-35)
#:export (managed-host-environment-type
@@ -68,6 +69,7 @@
machine-ssh-configuration?
this-machine-ssh-configuration
(host-name machine-ssh-configuration-host-name) ; string
+ (system machine-ssh-configuration-system) ; string
(build-locally? machine-ssh-configuration-build-locally?
(default #t))
(port machine-ssh-configuration-port ; integer
@@ -103,10 +105,12 @@ one from the configuration's parameters if one was not provided."
"Internal implementation of 'machine-remote-eval' for MACHINE instances with
an environment type of 'managed-host."
(maybe-raise-unsupported-configuration-error machine)
- (remote-eval exp (machine-ssh-session machine)
- #:build-locally?
- (machine-ssh-configuration-build-locally?
- (machine-configuration machine))))
+ (let ((config (machine-configuration machine)))
+ (remote-eval exp (machine-ssh-session machine)
+ #:build-locally?
+ (machine-ssh-configuration-build-locally? config)
+ #:system
+ (machine-ssh-configuration-system config))))
;;;
@@ -240,10 +244,29 @@ MACHINE's 'system' declaration do not exist on the machine."
device)
(return #t)))
+(define (machine-check-building-for-appropriate-system machine)
+ "Raise a '&message' error condition if MACHINE is configured to be built
+locally and the 'system' field does not match the '%current-system' reported
+by MACHINE."
+ (let ((config (machine-configuration machine))
+ (system (remote-system (machine-ssh-session machine))))
+ (when (and (machine-ssh-configuration-build-locally? config)
+ (not (string= system (machine-ssh-configuration-system config))))
+ (raise (condition
+ (&message
+ (message (format #f (G_ "incorrect target system \
+('~a' was given, while the system reports that it is '~a')~%")
+ (machine-ssh-configuration-system config)
+ system)))))))
+ (with-monad %store-monad (return #t)))
+
(define (check-deployment-sanity machine)
"Raise a '&message' error condition if it is clear that deploying MACHINE's
'system' declaration would fail."
+ ;; Order is important here -- an incorrect value for 'system' will cause
+ ;; invocations of 'remote-eval' to fail.
(mbegin %store-monad
+ (machine-check-building-for-appropriate-system machine)
(machine-check-file-system-availability machine)
(machine-check-initrd-modules machine)))
diff --git a/guix/remote.scm b/guix/remote.scm
index 5fecd954e..bcac64ea7 100644
--- a/guix/remote.scm
+++ b/guix/remote.scm
@@ -24,6 +24,7 @@
#:use-module (guix monads)
#:use-module (guix modules)
#:use-module (guix derivations)
+ #:use-module (guix utils)
#:use-module (ssh popen)
#:use-module (srfi srfi-1)
#:use-module (ice-9 match)
@@ -71,7 +72,7 @@ prerequisites of EXP are already available on the host at SESSION."
"Return a \"trampoline\" gexp that evaluates EXP and writes the evaluation
result to the current output port using the (guix repl) protocol."
(define program
- (scheme-file "remote-exp.scm" exp))
+ (program-file "remote-exp.scm" exp))
(with-imported-modules (source-module-closure '((guix repl)))
#~(begin
@@ -89,6 +90,7 @@ result to the current output port using the (guix repl) protocol."
(define* (remote-eval exp session
#:key
(build-locally? #t)
+ (system (%current-system))
(module-path %load-path)
(socket-name "/var/guix/daemon-socket/socket"))
"Evaluate EXP, a gexp, on the host at SESSION, an SSH session. Ensure that
@@ -96,10 +98,12 @@ all the elements EXP refers to are built and deployed to SESSION beforehand.
When BUILD-LOCALLY? is true, said dependencies are built locally and sent to
the remote store afterwards; otherwise, dependencies are built directly on the
remote store."
- (mlet %store-monad ((lowered (lower-gexp (trampoline exp)
- #:module-path %load-path))
- (remote -> (connect-to-remote-daemon session
- socket-name)))
+ (mlet* %store-monad ((lowered (lower-gexp (trampoline exp)
+ #:system system
+ #:guile-for-build #f
+ #:module-path %load-path))
+ (remote -> (connect-to-remote-daemon session
+ socket-name)))
(define inputs
(cons (lowered-gexp-guile lowered)
(lowered-gexp-inputs lowered)))
diff --git a/guix/ssh.scm b/guix/ssh.scm
index ede00133c..9b5ca6889 100644
--- a/guix/ssh.scm
+++ b/guix/ssh.scm
@@ -39,6 +39,7 @@
remote-inferior
remote-daemon-channel
connect-to-remote-daemon
+ remote-system
send-files
retrieve-files
retrieve-files*
@@ -282,6 +283,12 @@ be read. When RECURSIVE? is true, the closure of FILES is exported."
,(object->string
(object->string export))))))
+(define (remote-system session)
+ "Return the system type as expected by Nix, usually ARCHITECTURE-KERNEL, of
+the machine on the other end of SESSION."
+ (inferior-remote-eval '(begin (use-modules (guix utils)) (%current-system))
+ session))
+
(define* (send-files local files remote
#:key
recursive?

© 2015 - 2026 Jakob L. Kreuze

'#n412'>412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
@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}).

© 2015 - 2026 Jakob L. Kreuze