From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp11.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id WPVeDZ/hTWM69QAAbAwnHQ (envelope-from ) for ; Tue, 18 Oct 2022 01:13:35 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp11.migadu.com with LMTPS id sJ5xDZ/hTWPowQAA9RJhRA (envelope-from ) for ; Tue, 18 Oct 2022 01:13:35 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id AC7FDFAC0 for ; Tue, 18 Oct 2022 01:13:34 +0200 (CEST) Received: from localhost ([::1]:54564 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1okZIb-0006SG-QW for larch@yhetil.org; Mon, 17 Oct 2022 19:13:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36134) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1okZHq-0006QF-QE for guix-devel@gnu.org; Mon, 17 Oct 2022 19:12:48 -0400 Received: from mail-ej1-x62c.google.com ([2a00:1450:4864:20::62c]:44705) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1okZHn-0003vz-0L for guix-devel@gnu.org; Mon, 17 Oct 2022 19:12:46 -0400 Received: by mail-ej1-x62c.google.com with SMTP id w18so28335762ejq.11 for ; Mon, 17 Oct 2022 16:12:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=uVUqEYht14YoekdYpTZWzrpZWITEoT4IRqOl/+hWPMo=; b=lcMrpgFagysqsOQe+YXuQu3B8HvqsL+HPV/3fe0eE6tvtN9Gs+RpoHhXbTbJ7qBYPl PvcAupKeHull7xX8xZkWxLXpOHMIW4LMuPvZiKlFYWyMOownVA/tPUkcplzEZuAHGJHw fmQxk+XYb7n76MiMPRyV+Ydjj/z4DDtrD/KCXKPYX75U7jXDQAcx8bRHu57YiFDgHjZ2 m8gE2CzyUnnHdPjC3o3kvzy2rgVdk/13Oi/n5+uHb8dNfBTJ+rtIp7Pl+yGHNd4mMJzS 1dxzQrB1XmBkJROoAGg99P/TnmPZFrZpf6s0ml4gxFykY7o03JBqRgiJZoDNLXh/5lRO WCFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=uVUqEYht14YoekdYpTZWzrpZWITEoT4IRqOl/+hWPMo=; b=EfC++K8JcVm7JkCZiZ9ePsm20sQOcbr+4aXI8WxhDS0HKTERXs5peKxbtlovk7f31x 84xVQdUL3RK8uQr2Bb1bvce0mCXLMb3pWMS3D0coFSKGWAIcG1xHn3dUNNumK4subjbt CVD5k46T38RZ5jL16blPxDr8p7hl+idfMBjMVsrxorDqRHj8MqxbrsWnZnRB05RDlJW4 iuqrxxBxrSstYIzHImnmoQg38ty+xz89el8h7USREY4fv0brAsfmMhuQAoJFBfAuBZyr Mw+u9jLrz3/O+rf0KSoZ6B2BAKfSKU5TRSisNDFKxxAPl+Ez/BtHtF0H3ofwP2UqGIIf WPlQ== X-Gm-Message-State: ACrzQf1kJyF0VEv74EC3owygSqxOS6/TyP2ru2PcJ+GCrwMBtr+x8cfo Y5oEOTRhFmca693u3DSt7BjEKH2qE8p5OD1bo6k= X-Google-Smtp-Source: AMsMyM7zeng2ipKJKBpxROyZskIgeTVFVRKkE0Sibq26Urb/wddVajpS7e+Peb1YtlKr3Wrv60zaDiw/pFKt8tI8s/Q= X-Received: by 2002:a17:906:9b93:b0:78d:eb36:1ce7 with SMTP id dd19-20020a1709069b9300b0078deb361ce7mr40945ejc.621.1666048360996; Mon, 17 Oct 2022 16:12:40 -0700 (PDT) MIME-Version: 1.0 References: <331c0017d7a4842fd2919b330a3d3894@dismail.de> In-Reply-To: <331c0017d7a4842fd2919b330a3d3894@dismail.de> From: Zain Jabbar Date: Mon, 17 Oct 2022 13:12:29 -1000 Message-ID: Subject: Re: Creating an Emacs Home Configuration Service To: jbranso@dismail.de Cc: guix-devel@gnu.org Content-Type: text/plain; charset="UTF-8" Received-SPF: pass client-ip=2a00:1450:4864:20::62c; envelope-from=zaijab2000@gmail.com; helo=mail-ej1-x62c.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guix-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+larch=yhetil.org@gnu.org Sender: "Guix-devel" X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1666048415; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=uVUqEYht14YoekdYpTZWzrpZWITEoT4IRqOl/+hWPMo=; b=g30Y4pAZjPiEtihXhRMzFrzTUrc/SS+wg18pDG09vdRyYIa5jMA8B9G1yy/nzy3oEu1yKv /0vXZuXoH08Fg/U2rzx8hTJAgGNLl29zioj0WTZGqiMB3m/l4wyRVGz4tCNQTdH8cAd4fV rhkaGpRVZlet09wH4OjNpXlPMlpfMJAR/xlgAlhkw6y5a6uixtzRSvpzMJ3h4stENP5m50 Oq2TbGGbUcylh33g5p9N8/S35Zgok6kAa2ShQ7GAbMUBwj4g30ZZRROTOVWirb7eWZijA/ wWiFpmZsYqmecFJ26D6KMitTVin0HLtMYMvbqJOvC0FJfYYtMq8T8cxbC4f32A== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1666048415; a=rsa-sha256; cv=none; b=aUjzPUH2/lQkeYV4453SKaFOnNsSt72x+19Lh3p+LGkUAj+n7tqkOSe32No/yETVQFHvbo 5RFxuC+vxOGkiqPz/Ly8K34lUShVSv3FEo6gfyDY7nMZTnmGUusv/EYzNMt8IjuQp5bHyI EKXsKRaPB91BH1YntNlpWxaK/usSR7NRaOYbJ5GTCN5hAP/LakoWPIwq2RGC3R3APvZzgn 5LfU9TpxYE9tYUVAOAZdx4IPC+9sH/5usbSbKkB7YJaZp4Eg52WZTd/dnY+eHuZLwr5BpP G134mBUR4VIUaML6iBLQ8SY4hci3eYMwAN5CqNP7X38Q0nXSicWIZLoJCjockQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=lcMrpgFa; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -7.42 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=lcMrpgFa; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: AC7FDFAC0 X-Spam-Score: -7.42 X-Migadu-Scanner: scn0.migadu.com X-TUID: yN/wWbHBMseM 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 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. > > I believe that you are referring to using scheme records to configure the emacs service. :) > > I would recommend using (define-configuration ...) procedure. > > (There is a define-record-type* as well, but I think the consensus is that > define-configuration* is a little easier to use. Does better error handling > and can help you generate documentation from the code). > > You can find examples of that here: > > https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/mail.scm > > > > > -- > > Thank you, > > Zain Jabbar -- Thank you, Zain Jabbar 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 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. > > I believe that you are referring to using scheme records to configure the emacs service. :) > > I would recommend using (define-configuration ...) procedure. > > (There is a define-record-type* as well, but I think the consensus is that > define-configuration* is a little easier to use. Does better error handling > and can help you generate documentation from the code). > > You can find examples of that here: > > https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/mail.scm > > > > > -- > > Thank you, > > Zain Jabbar -- Thank you, Zain Jabbar