Re: Creating an Emacs Home Configuration Service

2022-10-19 Thread Zain Jabbar
Aloha All,

Thank you for your input! It's all been very constructive. I will do
my best on that patch.

On Wed, Oct 19, 2022 at 10:56 AM  wrote:
>
> October 19, 2022 4:25 PM, "Zain Jabbar"  wrote:
>
> > 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.
>
> I do not know if it is a needless abstraction.  I am just bouncing ideas
> around with you.  :)
>
> >
> > #+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).
>
> I would say when you submit your service to guix-devel others will give
> you some options too.  I like the idea of S-expressions though.
>
>
> > 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.
>
> Thanks for the explanation!



-- 
Thank you,
Zain Jabbar



Re: Creating an Emacs Home Configuration Service

2022-10-19 Thread Zain Jabbar
Aloha All,

Super awesome to hear from you! I'm quite star stuck.

Thank you for showcasing Andrew Tropin's rde project. I believe the
=features= abstraction have potential and make more intuitive sense
for the design of configurable programs. There is a lot for me to
learn from this design choice.

As it stands, =features= are not in Guix proper, are there plans to
merge them? How will they end up relating to the existing home
services feature set?

On Wed, Oct 19, 2022 at 5:36 AM Ludovic Courtès  wrote:
>
> Hi Zain, and welcome!
>
> Zain Jabbar  skribis:
>
> > Running =guix home search emacs= returns nothing. I also could not find an
> > email using =C-u M-x debbugs-gnu= about an Emacs configuration service.
> >
> > This is my first email to this mailing address. Please give me pointers on
> > formatting and further improvements.
> >
> > I have attempted to make an =emacs-home-service-type= so that it is
> > possible to configure Emacs using Guix home. This code is extremely
> > preliminary hence I don't even think it is worth sending as a patch. Also I
> > have never worked on a multi person Git project before and do not know how
> > to solve the keyring error I get when using guix pull. I will outline what
> > my code does and what features I would like to add.
>
> I am all for something like you describe, and the code you sent may be
> good starting point!
>
> The rde project¹ by Andrew Tropin et al. may be a good source of
> inspiration.  The “features” abstraction in particular seems to be
> well-suited for Emacs.  But overall it’s reasonable to start small, with
> a low-level approach to combine and configure Emacs packages.
>
> Thanks,
> Ludo’.
>
> ¹ https://trop.in/rde/manual



-- 
Thank you,
Zain Jabbar



Re: Creating an Emacs Home Configuration Service

2022-10-19 Thread Zain Jabbar
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  wrote:
>
> October 18, 2022 3:42 PM, "Zain Jabbar"  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 

Re: Creating an Emacs Home Configuration Service

2022-10-17 Thread Zain Jabbar
Aloha Guix Development Team,

Thank you for this email. Your advice was directed very kindly and is
very helpful. I have tried to revise the code based on your email. I
also checked the setting for plaintext mode in GMail; I hope this
makes the email easier to read.

First, I define a configuration (without serialization currently).

#+BEGIN_SRC scheme
(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"))
#+END_SRC

Then, I define an =emacs-configuration-service= that takes in a
configuration. This service will add packages in the =emacs-packages=
to the profile, and append the S-Expressions in =early-init= and
=init= to $XDG_CONFIG_HOME/emacs/early-init.el and
$XDG_CONFIG_HOME/emacs/init.el respectively. The service has
definition,

#+BEGIN_SRC scheme
(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")))
#+END_SRC

This version of the service is one big service that only takes in one
configuration file. So in order to configure bits and pieces of Emacs,
for example evil-mode and vertico we can append emacs-configurations
into one big configuration. I do this as follows.

#+BEGIN_SRC scheme
(define evil-configuration
  (emacs-configuration
   (emacs-packages (list (specification->package "emacs-evil")))
   (init '((evil-mode 1)

(define vertico-configuration
  (emacs-configuration
   (emacs-packages (list (specification->package "emacs-vertico")))
   (init '((vertico-mode 1)

(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)
(list evil-configuration vertico-configuration)))
#+END_SRC

We can actually go crazy with this idea. The next source block is a
generalization of the last one. Rather than declaring the list of
configurations, we have Guile figure out all of the bound
=emacs-configurations= in the current module and append them that way.

#+BEGIN_SRC scheme
(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)))
#+END_SRC

What further improvements could I add to this system? The end goal
(hopefully) is to help add another home service to Guix. I was
inspired by David Wilson's call to action during his Guix Home talk at
the 10 year anniversary event.



On Mon, Oct 17, 2022 at 12:09 PM  wrote:
>
> October 17, 2022 2:38 AM, "Zain Jabbar"  wrote:
>
> > Aloha Guix Development Team,
> >
> > Running =guix home search emacs= returns nothing. I also could not find an 
> > email using =C-u M-x
> > debbugs-gnu= about an Emacs configuration service.
> >
> > This is my first email to this mailing address. Please give me pointers on 
> > formatting and further
> > improvements.
>
> I think you sent an html email.  Generally you want to send plain text 
> emails.  :)
>
> > I have attempted to make an =emacs-home-service-type= so that it is 
> > possible to configure Emacs
> > using Guix home. This code is extremely preliminary hence I don't even 
> > think it is worth sending as
> > a patch. Also I have never worked on a multi person Git project before and 
> > do not know how to solve
> > the keyring error I get when using guix pull. I will outline wha

Creating an Emacs Home Configuration Service

2022-10-17 Thread Zain Jabbar
Aloha Guix Development Team,

Running =guix home search emacs= returns nothing. I also could not find an
email using =C-u M-x debbugs-gnu= about an Emacs configuration service.

This is my first email to this mailing address. Please give me pointers on
formatting and further improvements.

I have attempted to make an =emacs-home-service-type= so that it is
possible to configure Emacs using Guix home. This code is extremely
preliminary hence I don't even think it is worth sending as a patch. Also I
have never worked on a multi person Git project before and do not know how
to solve the keyring error I get when using guix pull. I will outline what
my code does and what features I would like to add.

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


(define-public emacs-init-service-type
  (service-type (name 'home-emacs)
(extensions
(list (service-extension
home-profile-service-type
(lambda (config) (list emacs-next)))
  (service-extension
home-files-service-type
(lambda (config)
 (list
  `(".config/emacs/early-init.el"
,(scheme-file
  "early-init.el"
  '((mapc
 'load (file-expand-wildcards
"~/.config/emacs/early-services/*.el")))
  #:splice? #t))
  `(".config/emacs/init.el"
,(scheme-file
  "init.el"
  '((mapc
 'load (file-expand-wildcards
"~/.config/emacs/services/*.el")))
  #:splice? #t)))
(default-value #f)
(description "Configures Emacs init.el")))
#+END_SRC

I define a general configuration service generator which takes in four
things:
1. The =name= of the service
2. The configuration to be ran in =init.el=
3. The configuration to be ran in =early-init.el=
4. The packages in Guix to be added to the =home-profile=.

After giving the =name=, =packages=, and =config.el= files we get a new
service type that we can add to our home declaration. This service will
then add a file in
=~/.config/emacs/services/emacs-{NAME}-configuration.el=. I then have
another service that places an =init.el= which loads everything in the
service directory.

If we want to install and configure =evil-mode= using this =home-service=
we may define the following somewhere.

#+BEGIN_SRC scheme
(define-public emacs-evil-service-type
  (emacs-configuration-service
   'evil #:emacs-packages (list emacs-evil)
   #:init '((evil-mode 1
#+END_SRC

Within our =home-environment= we may add the service using:

#+BEGIN_SRC scheme
(home-environment
 ;; ...Things in the home-environment...
 (services
  (list
   ;; ...Other Services...
   (service emacs-evil-service-type
#+END_SRC

There are some missing features I want to add.

1. Have the =home-emacs-*-service-type= service-types add to the =init.el=
directly rather than within a folder to be loaded. I couldn't add two files
with the same name to the store. So I have emacs-evil.el in the store to be
placed separately later rather than appending to the existing init.el file.

2. Have Emacs update whenever the =home-environment= is updated. Meaning,
if I did not add =(service emacs-evil-service-type)= in my
=home-environment= then obviously =M-x evil-mode= should not work. But
after adding the service then I want =M-x evil-mode= to work without having
to restart Emacs. I do not understand the Emacs loading system on Guix well
enough to know why it does not work. Skipping all of the =home-service=
stuff, running =guix install emacs-evil-mode= then
=(guix-emacs-autoload-packages)= does not let emacs know that =evil-mode=
is installed. I would need to close Emacs and start Emacs again for Emacs
to know about =evil-mode= being installed.

3. Use configurations somehow. I have completely neglected this feature in
my system. I do not know what would be useful there.

-- 
Thank you,
Zain Jabbar