From patchwork Sun Jun 18 08:49:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Efraim Flashner X-Patchwork-Id: 51031 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id E82C327BBE2; Sun, 18 Jun 2023 09:50:23 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id A8E0A27BBE9 for ; Sun, 18 Jun 2023 09:50:20 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qAo6o-0005Jr-Ll; Sun, 18 Jun 2023 04:50:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qAo6m-0005JU-Ca for guix-patches@gnu.org; Sun, 18 Jun 2023 04:50:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qAo6m-0002Mv-1t for guix-patches@gnu.org; Sun, 18 Jun 2023 04:50:04 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qAo6l-0005DF-SK for guix-patches@gnu.org; Sun, 18 Jun 2023 04:50:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#63909] [PATCH v2] home: Add inputrc service. Resent-From: Efraim Flashner Original-Sender: "Debbugs-submit" Resent-CC: , guix-patches@gnu.org Resent-Date: Sun, 18 Jun 2023 08:50:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63909 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 63909@debbugs.gnu.org, ludo@gnu.org Cc: paren@disroot.org, efraim@flashner.co.il, andrew@trop.in, ( , Andrew Tropin , Ludovic =?utf-8?q?Co?= =?utf-8?q?urt=C3=A8s?= X-Debbugs-Original-To: guix-patches@gnu.org, Ludovic =?utf-8?q?Court=C3=A8s?= X-Debbugs-Original-Cc: paren@disroot.org, 63909@debbugs.gnu.org, Efraim Flashner , Andrew Tropin X-Debbugs-Original-Xcc: ( , Andrew Tropin , Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 63909-submit@debbugs.gnu.org id=B63909.168707820120007 (code B ref 63909); Sun, 18 Jun 2023 08:50:03 +0000 Received: (at 63909) by debbugs.gnu.org; 18 Jun 2023 08:50:01 +0000 Received: from localhost ([127.0.0.1]:53164 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qAo6i-0005Cb-Ey for submit@debbugs.gnu.org; Sun, 18 Jun 2023 04:50:01 -0400 Received: from mail-wm1-f51.google.com ([209.85.128.51]:45104) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qAo6b-0005Bz-NP for 63909@debbugs.gnu.org; Sun, 18 Jun 2023 04:49:55 -0400 Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-3f8fb0e7709so17918505e9.2 for <63909@debbugs.gnu.org>; Sun, 18 Jun 2023 01:49:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687078187; x=1689670187; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=cYUsGkRe2rKsTrlSLm9OKezfz3JDQcrXjsDwAiQi+9Q=; b=oRJylU7OlFndtjjiLf1bWFQ/zuyGXrb5kpwFprKWFBH1OlwOw1GNLwbUTfXlz0F6Y0 Bwcl4fUTeT3sfLjw3draeUozzaeIG9Vxa+CRyzWWg3lA0Q6sVmc05LfGmdBFAqXbC0h4 AMira2h4lVlEgWBCeWKlFv5kWISxBiOHENWeDjjfPDJb4VtFYrd2QSzvYYnskuiRkszL UO6jKh3n5bJsK6oNQqnf9tuEf6kfOLHS3z4jo3d21p9Sm7cYYBFUwR/8GJfF/GlLd2yM p1I5BmS2FrzUe6m4YH567cXnuut6lRLmEpL81ItbWUWZB1STFOpWdeX94wXDZ9Rk0t99 VBSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687078187; x=1689670187; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=cYUsGkRe2rKsTrlSLm9OKezfz3JDQcrXjsDwAiQi+9Q=; b=d6axEzxSzzLc26hfHgEsJFhYUqjTmFByLYuJd7jq+9zGL/+vEK8gI6BGv5wInHWz5b /OqZcC++dmGUtv0j4GOlnDZ90oSUqO95wR08B3/rCIN/nmMHhPuVxPiFWxsFKGDuSxQr 4fmSEW3IZ+OeSD61qh/UAU+WHttj2+0LnBjQF8zLKFZp4Fj2LWOIFhR8q4RYF1DX5UWE rZEy+5/k0I4jQuBc1RTfXCoIibCNr4VS1toTOcPeCgIJ34tuHc/xx3KqrcWS4ky+W4XS GRpnrBfz4vjUeO28EMWszw1ApmKUrSlbEE2W91/gJnh30ydGGigoIX4T9TtVWhAHYO6q Q1qw== X-Gm-Message-State: AC+VfDzYjIx7emrgBkLhfHJIfWEvbUQIfnfEu1pDY4si9JRMWlStDJjH La4Tj1Au7Eknj8ukYdZbejfsbBWn23gNUw== X-Google-Smtp-Source: ACHHUZ6SHapk94J0lalH0hlNEAMiUZCr0461xWub0WC8oQN+fjA6/aTEIWMF2GYDsfmpeXb2u0QEQA== X-Received: by 2002:a1c:f718:0:b0:3f7:e65b:5252 with SMTP id v24-20020a1cf718000000b003f7e65b5252mr5505773wmh.1.1687078187374; Sun, 18 Jun 2023 01:49:47 -0700 (PDT) Received: from localhost ([37.46.46.3]) by smtp.gmail.com with ESMTPSA id t8-20020a7bc3c8000000b003f6129d2e30sm7233892wmj.1.2023.06.18.01.49.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Jun 2023 01:49:46 -0700 (PDT) From: Efraim Flashner Date: Sun, 18 Jun 2023 11:49:15 +0300 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: <87pm5vseyu.fsf@gnu.org> References: <87pm5vseyu.fsf@gnu.org> MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/home/services/shells.scm (home-inputrc-service-type, home-inputrc-configuration): New variables. (serialize-inputrc-key-bindings, serialize-inputrc-variables, serialize-inputrc-conditional-constructs, serialize-inputrc-extra-content): New procedures. * doc/guix.texi (Shells Home Services): Document it. --- doc/guix.texi | 129 +++++++++++++++++++++++++++++++++ gnu/home/services/shells.scm | 134 ++++++++++++++++++++++++++++++++++- 2 files changed, 262 insertions(+), 1 deletion(-) base-commit: e4087930f3ad60918689be5f4bca4ce3e22429f5 diff --git a/doc/guix.texi b/doc/guix.texi index 9232c82b4b..72ab941243 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -42797,6 +42797,135 @@ Shells Home Services @end deftp +@subsubheading Inputrc Profile Service +@cindex inputrc +@cindex readline + +The @uref{https://tiswww.cwru.edu/php/chet/readline/rltop.html, GNU +Readline package} includes Emacs and vi editing modes, with the ability +to customize the configuration with settings in the @file{~/.inputrc} +file. With the @code{gnu home services shells} module, you can setup +your readline configuration in a predictable manner, as shown below. +For more information about configuring an @file{~/.inputrc} file, +@pxref{Readline Init File,,, readline, GNU Readline}. + +@defvar home-inputrc-service-type + +This is the service to setup various @file{.inputrc} configurations. The +settings in @file{.inputrc} are read by all programs which are linked +with GNU Readline. + +Here is an example of a service and its configuration that you could add +to the @code{services} field of your @code{home-environment}: + +@lisp +(service home-inputrc-service-type + (home-inputrc-configuration + (key-bindings + `(("Control-l" . "clear-screen"))) + (variables + `(("bell-style" . "visible") + ("colored-completion-prefix" . #t) + ("editing-mode" . "vi") + ("show-mode-in-prompt" . #t))) + (conditional-constructs + `(("$if mode=vi" . + ,(home-inputrc-configuration + (variables + `(("colored-stats" . #t) + ("enable-bracketed-paste" . #t))))) + ("$else" . + ,(home-inputrc-configuration + (variables + `(("show-all-if-ambiguous" . #t))))) + ("endif" . #t) + ("$include" . "/etc/inputrc") + ("$include" . ,(file-append + (specification->package "readline") + "/etc/inputrc")))))) +@end lisp + +The example above starts with a combination of @code{key-bindings} and +@code{variables}. The @code{conditional-constructs} show how it is +possible to add conditionals and includes. In the example above +@code{colored-stats} is only enabled if the editing mode is @code{vi} +style, and it also reads any additional configuration located in +@file{/etc/inputrc} or in @file{/gnu/store/@dots{}-readline/etc/inputrc}. + +The value associated with a @code{home-inputrc-service-type} instance +must be a @code{home-inputrc-configuration} record, as described below. + +@end defvar + +@anchor{home-inputrc-configuration} +@deftp {Data Type} home-inputrc-configuration +Available @code{home-inputrc-configuration} fields are: + +@table @asis +@item @code{key-bindings} (default: @code{'()}) (type: alist) +Association list of readline key bindings to be added to the +@file{~/.inputrc} file. + +@lisp +'((\"Control-l\" . \"clear-screen\")) +@end lisp + +turns into + +@example +Control-l: clear-screen +@end example + +@item @code{variables} (default: @code{'()}) (type: alist) +Association list of readline variables to set. + +@lisp +'((\"bell-style\" . \"visible\") + (\"colored-completion-prefix\" . #t)) +@end lisp + +turns into + +@example +set bell-style visible +set colored-completion-prefix on +@end example + +@item @code{conditional-constructs} (default: @code{'()}) (type: alist) +Association list of conditionals to add to the initialization file. This +includes @command{$if}, @command{else}, @command{endif} and @command{include} +and they receive a value of another @command{home-inputrc-configuration}. + +@lisp +(conditional-constructs + `((\"$if mode=vi\" . + ,(home-inputrc-configuration + (variables + `((\"show-mode-in-prompt\" . #t))))) + (\"$else\" . + ,(home-inputrc-configuration + (key-bindings + `((\"Control-l\" . \"clear-screen\"))))) + (\"$endif\" . #t))) +@end lisp + +turns into + +@example +$if mode=vi +set show-mode-in-prompt on +$else +Control-l: clear-screen +$endif +@end example + +@item @code{extra-content} (default: @code{""}) (type: text-config) +Extra content appended as-is to the configuration file. Run @command{man +readline} for more information about all the configuration options. + +@end table +@end deftp + @node Mcron Home Service @subsection Scheduled User's Job Execution diff --git a/gnu/home/services/shells.scm b/gnu/home/services/shells.scm index f05f2221d6..415b5470c5 100644 --- a/gnu/home/services/shells.scm +++ b/gnu/home/services/shells.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2021 Andrew Tropin ;;; Copyright © 2021 Xinglu Chen +;;; Copyright © 2023 Efraim Flashner ;;; ;;; This file is part of GNU Guix. ;;; @@ -44,7 +45,10 @@ (define-module (gnu home services shells) home-fish-service-type home-fish-configuration - home-fish-extension)) + home-fish-extension + + home-inputrc-service-type + home-inputrc-configuration)) ;;; Commentary: ;;; @@ -626,6 +630,134 @@ (define home-fish-service-type (description "\ Install and configure Fish, the friendly interactive shell."))) + +;;; +;;; Readline. +;;; + +(define (serialize-inputrc-key-bindings field-name val) + #~(string-append + #$@(map + (match-lambda + ((key . value) + #~(string-append #$key ": " #$value "\n"))) + val))) + +(define (serialize-inputrc-variables field-name val) + #~(string-append + #$@(map + (match-lambda + ((key . #f) + #~(string-append "set " #$key " off\n")) + ((key . #t) + #~(string-append "set " #$key " on\n")) + ((key . value) + #~(string-append "set " #$key " " #$value "\n"))) + val))) + +(define (serialize-inputrc-conditional-constructs field-name val) + #~(string-append + #$@(map + (match-lambda + (("$endif" . _) + "$endif\n") + (("$include" . value) + #~(string-append "$include " #$value "\n")) + ;; TODO: key can only be "$if" or "$else". + ((key . value) + #~(string-append #$key "\n" + #$(serialize-configuration + value + home-inputrc-configuration-fields)))) + val))) + +(define (serialize-inputrc-extra-content field-name value) + #~(if (string=? #$value "") "" (string-append #$value "\n"))) + +(define-configuration home-inputrc-configuration + (key-bindings + (alist '()) + "Association list of readline key bindings to be added to the +@code{~/.inputrc} file. This is where code like this: + +@lisp +'((\"Control-l\" . \"clear-screen\")) +@end lisp + +turns into + +@example +Control-l: clear-screen +@end example" + (serializer serialize-inputrc-key-bindings)) + (variables + (alist '()) + "Association list of readline variables to set. This is where configuration +options like this: + +@lisp +'((\"bell-style\" . \"visible\") + (\"colored-completion-prefix\" . #t)) +@end lisp + +turns into + +@example +set bell-style visible +set colored-completion-prefix on +@end example" + (serializer serialize-inputrc-variables)) + (conditional-constructs + (alist '()) + "Association list of conditionals to add to the initialization file. This +includes @command{$if}, @command{else}, @command{endif} and @command{include} +and they receive a value of another @command{home-inputrc-configuration}. + +@lisp +(conditional-constructs + `((\"$if mode=vi\" . + ,(home-inputrc-configuration + (variables + `((\"show-mode-in-prompt\" . #t))))) + (\"$else\" . + ,(home-inputrc-configuration + (key-bindings + `((\"Control-l\" . \"clear-screen\"))))) + (\"$endif\" . #t))) +@end lisp + +turns into + +@example +$if mode=vi +set show-mode-in-prompt on +$else +Control-l: clear-screen +$endif +@end example" + (serializer serialize-inputrc-conditional-constructs)) + (extra-content + (string "") + "Extra content appended as-is to the configuration file. Run @command{man +readline} for more information about all the configuration options." + (serializer serialize-inputrc-extra-content))) + +(define (home-inputrc-files config) + (list + `(".inputrc" + ,(mixed-text-file "inputrc" + (serialize-configuration + config + home-inputrc-configuration-fields))))) + +(define home-inputrc-service-type + (service-type (name 'inputrc) + (extensions + (list (service-extension home-files-service-type + home-inputrc-files))) + (default-value (home-inputrc-configuration)) + (description "Configure readline in @code{.inputrc}."))) + (define (generate-home-shell-profile-documentation) (generate-documentation