guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Creating an Emacs Home Configuration Service


From: Zain Jabbar
Subject: Re: Creating an Emacs Home Configuration Service
Date: Wed, 19 Oct 2022 10:25:31 -1000

Aloha All,

Thank you for your insightful messages. Sorry my code did not work as
smoothly as I would have liked. I have a =home-environment= definition
that hopefully works for you. You can put everything into one
configuration as you described. I do that in the following source
block. For some reason I liked the idea of separate definitions of
each package, so that Guile and Guix Home kind of acts like a
=use-package= declaration. Though that was needless abstraction on my
end.

#+BEGIN_SRC scheme
(use-modules (srfi srfi-1)
     (ice-9 pretty-print)
     (gnu home)
     (gnu packages)
     (gnu services)
     (gnu home services)
     (gnu services configuration)
     (guix gexp)
     (guix transformations))

(define file-likes? (list-of file-like?))

(define-configuration/no-serialization emacs-configuration
  (emacs-packages
   (file-likes (list (specification->package "emacs-next"))) "Files")
  (early-init
   (list '()) "Early-Init")
  (init
   (list '()) "Init"))

(define-public emacs-configuration-service
  (service-type (name (symbol-append 'emacs-configuration))
(extensions
(list (service-extension
home-profile-service-type
(lambda (config) (emacs-configuration-emacs-packages config)))
       (service-extension
home-xdg-configuration-files-service-type
(lambda (config)
  (list
   `("emacs/init.el" ,(scheme-file "init.el"
  (emacs-configuration-init config)
  #:splice? #:t))
   `("emacs/early-init.el" ,(scheme-file "early-init.el"
  (emacs-configuration-early-init config)
  #:splice? #:t)))))))
(default-value (emacs-configuration))
(description "Configures Emacs init.el")))

(define-public minimal-home-environment
  (home-environment
   (services
    (list
     (service emacs-configuration-service
      (emacs-configuration
       (emacs-packages
(list
(specification->package "bash")
(specification->package "emacs-next")
(specification->package "emacs-debbugs")
(specification->package "emacs-evil")
(specification->package "emacs-paredit")
(specification->package "emacs-anzu")))
       (init '((evil-mode 1)
       ;; Please add more config here
       ;; Begining of emacs init configuration after evil-mode 1

       ;; End emacs init configuration
       ))
       (early-init '((setq warning-suppress-log-types '((comp) (comp)))
     (setq warning-suppress-types '((comp) (comp))))))))))) ; A
serious stack of pringles here

minimal-home-environment
#+END_SRC

I saved this file to =minimal-working-example.scm= and ran a container using
=guix home -N --share=/tmp container ./minimal-working-example.scm=.
This should spawn a shell in which you can run =emacs= (as terminal).
Furthermore we can also run the info help command and get to the
debbugs page.

The =init= and =early-init= configuration options take in
S-Expressions not files. Under the hood the service uses =scheme-file=
which takes in an expression. I am open to suggestions for other file
mechanisms, like if, for example, G-Expressions are more natural here.
I found that I did not know how to naturally append G-Expressions
together and that the S-Expressions can "bleed" into the config using
backquotes. So I chose just sticking in a list of expressions for
Emacs. Something Andrew Tropin taught me, if you are working in a
=*.scm= file and you want to evaluate elisp, use =M-x eval-region= or
=M-x edit-indirect-region= (with the usual stipulation that if you do
this very often we can bind it to a key).

If my interpretation of 13.1 Declaring the Home Environment is
correct, we should expect an error associated with XDG_RUNTIME_DIR as
the necessary variables will be set via the Operating-System
declaration. The next error I believe is emacs wanting to make a file
where the home container does not have read or write permissions. My
=guix home= declaration with the =share= parameter should hopefully
help with this error. Oddly enough if we do not specify the
installation of =bash=, Emacs says it cannot uncompress the info
manuals because there is no =sh=. That is why I included =bash= into
the emacs packages list. I do think a lot of these "solutions" will be
unncessecary if users were to use =guix home reconfigure= rather than
user the container. Though it's nice to debug them there.

On Wed, Oct 19, 2022 at 8:19 AM <jbranso@dismail.de> wrote:
>
> October 18, 2022 3:42 PM, "Zain Jabbar" <zaijab2000@gmail.com> wrote:
>
> > Here is a minimal reproducible(-ish needs change in module name)
> > example configuration which installs =emacs-debbugs= (and not much
> > else).
>
> Cool I am CC-ing guix devel.
>
> > #+BEGIN_SRC scheme
> > (define-module (zaijab minimal-working-example)
> > #:use-module (srfi srfi-1)
> > #:use-module (ice-9 pretty-print)
> > #:use-module (gnu home)
> > #:use-module (gnu packages)
> > #:use-module (gnu services)
> > #:use-module (gnu home services)
> > #:use-module (gnu services)
> > #:use-module (gnu services configuration)
> > #:use-module (guix gexp)
> > #:use-module (guix transformations))
> >
> > (define file-likes? (list-of file-like?))
> >
> > (define-configuration/no-serialization emacs-configuration
> > (emacs-packages
> > (file-likes (list (specification->package "emacs-next"))) "Files")
> > (early-init
> > (list '()) "Early-Init")
> > (init
> > (list '()) "Init"))
> >
> > (define debuggs-configuration
> > (emacs-configuration
> > (emacs-packages (list (specification->package "emacs-debbugs")))))
> >
> > (define-public total-emacs-configuration
> > (fold (lambda (config-1 config-2) (emacs-configuration
> > (init (append (emacs-configuration-init config-1)
> > (emacs-configuration-init config-2)))
> > (early-init (append (emacs-configuration-early-init config-1)
> > (emacs-configuration-early-init config-2)))
> > (emacs-packages (append (emacs-configuration-emacs-packages config-1)
> > (emacs-configuration-emacs-packages config-2)))))
> > (emacs-configuration)
> >
> > (filter emacs-configuration?
> > (map variable-ref
> > (filter variable-bound?
> > (hash-map->list (lambda (x y) y) (struct-ref (current-module) 0)))))))
> >
> > (define-public emacs-configuration-service
> > (service-type (name (symbol-append 'emacs-configuration))
> > (extensions
> > (list (service-extension
> > home-profile-service-type
> > (lambda (config) (emacs-configuration-emacs-packages config)))
> > (service-extension
> > home-xdg-configuration-files-service-type
> > (lambda (config)
> > (list
> > `("emacs/init.el" ,(scheme-file "init.el"
> > (emacs-configuration-init config)
> > #:splice? #:t))
> > `("emacs/early-init.el" ,(scheme-file "early-init.el"
> > (emacs-configuration-early-init config)
> > #:splice? #:t)))))))
> > (default-value (emacs-configuration))
> > (description "Configures Emacs init.el")))
> >
> > (define-public minimal-home-environment
> > (home-environment
> > (services (list (service emacs-configuration-service
> > total-emacs-configuration)))))
> >
> > minimal-home-environment
> > #+END_SRC
>
> I wonder why you do the define total-emacs-configuration...is it possible
> to define an emacs-configuration something like this?
>
> Forgive the possibly wrong syntax, I don't use guix home
>
> (services
> (service emacs-configuration-service
> (emacs-configuration
> (packages
> (list emacs-debbugs
> emacs-evil
> emacs-paredit
> emacs-anzu))
> (init (text-file "init-file.el"
> "(evil-mode 1)\n
> ;; other configuration stuff")))))
>
> > I tested this using =guix home container -N
> > minimal-working-example.scm=. Typing =M-x debbugs-gnu= gives a menu of
> > bugs. I made sure the debbugs configuration is necessary by commenting
> > it out, re-running =guix home container= and seeing that =M-x debb
> > [TAB]= pulls up nothing. I think it works. Woo-hoo!
>
> When I tested the home container via terminal foot I get a weird error:
>
> warning: XDG_RUNTIME_DIR doesn't exists, on-first-login script
> won't execute anything. You can check if xdg runtime directory exists,
> XDG_RUNTIME_DIR variable is set to appropriate value and manually execute the
> script by running '$HOME/.guix-home/on-first-login'-bash-5.1$ emacs
> emacs: Terminal type foot is not defined.
> If that is not the actual type of terminal you have,
> use the Bourne shell command 'TERM=...; export TERM' (C-shell:
> 'setenv TERM ...') to specify the correct type. It may be necessary
> to do 'unset TERMINFO' (C-shell: 'unsetenv TERMINFO') as well.
>
> That's probably just foot being weird.
>
> In lxterminal, emacs started fine. However, doing a M-x info RET
>
> m Debbugs RET
>
> I get this error in emacs:
>
> "Creating file with prefx: No such file or directory /tmp/jka-com"
>
> Anyway, definitely go ahead and send it to guix-patches!
>
> > Thank you for telling me about the =,build= meta command. It looks
> > very useful! I will need to figure out how to use it from =M-x
> > geiser-guile=. I have built this code by doing the following:
> > - open VTerm
> > - guix repl
> > - ,use (guix)
> > - ,use (MODULE-NAME) ;; in my case this was (zaijab minimal-working-example)
> > - ,build minimal-home-environment
>
> Once you get geiser set up and clone the git repo, and compile everything...
> inside the guix-src code...whatever file you are currently working on
> C-c C-a opens up that file in the repl.  It's super awesome to be able to
> throw in some code evaluate it on the fly.
>
> https://video.hardlimit.com/c/the_gnu_guy/videos
>
> > I will be learning how to use the Git patching system soon. I will add
> > more documentation when I submit the patch. I'll be sure to CC you as
> > well. Thank you for your assistance.
> >
> > On Tue, Oct 18, 2022 at 8:42 AM <jbranso@dismail.de> wrote:
> >
> >> October 18, 2022 1:55 PM, "Zain Jabbar" <zaijab2000@gmail.com> wrote:
> >>
> >> Aloha Guix Development Team,
> >>
> >> Thank you for your email. I attribute my successes to the fantastic
> >> documentation and my failures (as you will see in this email) to my
> >> own inability to read the documentation.
> >>
> >> I meant to mention, have you tried using ",build" in a geiser repl?
> >> It lets you build derivations/gexps and shows you the output in
> >> the store. I have found that super helpful when building my only
> >> guix service (not merged yet).
> >>
> >> From what I can tell, yes. Emacs does find the packages you install
> >> using this mechanism and loading them behaves as though you installed
> >> from a manifest. Let me know if you have a package you wish to test. I
> >> can email the results.
> >>
> >> emacs-debbugs. If it works, then that is awesome! Well done!
> >>
> >> But I would need more guidance to answer this question fully. There
> >> are some points of confusion I have relating to profiles and package
> >> availability. I will try to give my best answer using the
> >> documentation, source code, then a demo.
> >>
> >> One thing I can say for sure is that the packages are installed using
> >> the =home-profile-service-type=. According to the documentation at
> >> 13.3.1 Essential Home Services the =home-profile-service-type= can be
> >> "extended with a list of packages if you want to install additional
> >> packages into your profile".
> >>
> >> According to the source code in guix/gnu/home/services.scm
> >> #+BEGIN_SRC scheme
> >> ;; [In the big comment block line 76]
> >> ;;; home-profile-service-type is almost the same as
> >> profile-service-type, at least
> >> ;;; for now.
> >> .... ;; [Within the definition for home-profile-service-type (line 161)]
> >> (description
> >> "This is the @dfn{home profile} and can be found in
> >> @file{~/.guix-home/profile}. It contains packages and
> >> configuration files that the user has declared in their
> >> @code{home-environment} record."))
> >> #+END_SRC
> >>
> >> It appears that using this configuration it installs it into the
> >> =~/.guix-home/profile=. Here is where I get a bit confused, when
> >> running =guix package --list-profiles= I get
> >> =/home/zjabbar/.config/guix/current= and
> >> =/home/zjabbar/.guix-profile=, neither of which are my home profile.
> >>
> >> Here is a demo.
> >>
> >> I do not have the =emacs-suneater-theme= package installed using my 
> >> manifest.
> >>
> >> =guix package -I suneater= returns nothing when run in the terminal.
> >>
> >> After saving this configuration in the module:
> >> #+BEGIN_SRC scheme
> >> (define theme-configuration
> >> (emacs-configuration
> >> (emacs-packages (list (specification->package "emacs-suneater-theme")))
> >> (init '((load-theme 'suneater t)))))
> >> #+END_SRC
> >>
> >> I find that Guix downloads and builds the package. After restarting
> >> Emacs, it comes up with the new theme and =M-x describe-theme= finds
> >> it and everything. That being said, =guix package -I suneater= *still*
> >> returns nothing when run in the terminal. I suppose it's because the
> >> theme was installed without using the =guix install= command
> >> specifically.
> >>
> >> =guix package -A suneater= does show me that suneater is available.
> >> However after deleting or commenting out the configuration in that
> >> source block, Emacs does not load the theme and Emacs cannot find the
> >> theme using =M-x describe-theme=. But =guix package -A suneater= still
> >> shows me that suneater is available. So it was removed according to
> >> Emacs but not to guix. I am likely not looking at the right =guix
> >> package= options.
> >>
> >> It sounds like you have created the home-emacs service is a way that works.
> >> I think your next move would be submit it guix-patches@gnu.org.
> >> Feel free to CC me in the email.
> >>
> >> https://git-send-email.io
> >>
> >> Thanks,
> >>
> >> Joshua
> >
> > --
> > Thank you,
> > Zain Jabbar
> >
> > On Tue, Oct 18, 2022 at 8:42 AM <jbranso@dismail.de> wrote:
> >
> >> October 18, 2022 1:55 PM, "Zain Jabbar" <zaijab2000@gmail.com> wrote:
> >>
> >> Aloha Guix Development Team,
> >>
> >> Thank you for your email. I attribute my successes to the fantastic
> >> documentation and my failures (as you will see in this email) to my
> >> own inability to read the documentation.
> >>
> >> I meant to mention, have you tried using ",build" in a geiser repl?
> >> It lets you build derivations/gexps and shows you the output in
> >> the store. I have found that super helpful when building my only
> >> guix service (not merged yet).
> >>
> >> From what I can tell, yes. Emacs does find the packages you install
> >> using this mechanism and loading them behaves as though you installed
> >> from a manifest. Let me know if you have a package you wish to test. I
> >> can email the results.
> >>
> >> emacs-debbugs. If it works, then that is awesome! Well done!
> >>
> >> But I would need more guidance to answer this question fully. There
> >> are some points of confusion I have relating to profiles and package
> >> availability. I will try to give my best answer using the
> >> documentation, source code, then a demo.
> >>
> >> One thing I can say for sure is that the packages are installed using
> >> the =home-profile-service-type=. According to the documentation at
> >> 13.3.1 Essential Home Services the =home-profile-service-type= can be
> >> "extended with a list of packages if you want to install additional
> >> packages into your profile".
> >>
> >> According to the source code in guix/gnu/home/services.scm
> >> #+BEGIN_SRC scheme
> >> ;; [In the big comment block line 76]
> >> ;;; home-profile-service-type is almost the same as
> >> profile-service-type, at least
> >> ;;; for now.
> >> .... ;; [Within the definition for home-profile-service-type (line 161)]
> >> (description
> >> "This is the @dfn{home profile} and can be found in
> >> @file{~/.guix-home/profile}. It contains packages and
> >> configuration files that the user has declared in their
> >> @code{home-environment} record."))
> >> #+END_SRC
> >>
> >> It appears that using this configuration it installs it into the
> >> =~/.guix-home/profile=. Here is where I get a bit confused, when
> >> running =guix package --list-profiles= I get
> >> =/home/zjabbar/.config/guix/current= and
> >> =/home/zjabbar/.guix-profile=, neither of which are my home profile.
> >>
> >> Here is a demo.
> >>
> >> I do not have the =emacs-suneater-theme= package installed using my 
> >> manifest.
> >>
> >> =guix package -I suneater= returns nothing when run in the terminal.
> >>
> >> After saving this configuration in the module:
> >> #+BEGIN_SRC scheme
> >> (define theme-configuration
> >> (emacs-configuration
> >> (emacs-packages (list (specification->package "emacs-suneater-theme")))
> >> (init '((load-theme 'suneater t)))))
> >> #+END_SRC
> >>
> >> I find that Guix downloads and builds the package. After restarting
> >> Emacs, it comes up with the new theme and =M-x describe-theme= finds
> >> it and everything. That being said, =guix package -I suneater= *still*
> >> returns nothing when run in the terminal. I suppose it's because the
> >> theme was installed without using the =guix install= command
> >> specifically.
> >>
> >> =guix package -A suneater= does show me that suneater is available.
> >> However after deleting or commenting out the configuration in that
> >> source block, Emacs does not load the theme and Emacs cannot find the
> >> theme using =M-x describe-theme=. But =guix package -A suneater= still
> >> shows me that suneater is available. So it was removed according to
> >> Emacs but not to guix. I am likely not looking at the right =guix
> >> package= options.
> >>
> >> It sounds like you have created the home-emacs service is a way that works.
> >> I think your next move would be submit it guix-patches@gnu.org.
> >> Feel free to CC me in the email.
> >>
> >> https://git-send-email.io
> >>
> >> Thanks,
> >>
> >> Joshua
> >
> > --
> > Thank you,
> > Zain Jabbar



-- 
Thank you,
Zain Jabbar



reply via email to

[Prev in Thread] Current Thread [Next in Thread]