From 75f3b1a12debaac9b1b6368245ac75a236430296 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Sat, 2 Aug 2014 19:24:50 -0400 Subject: [PATCH] Add (guix build emacs-utils). * guix/build/emacs-utils.scm: New file. * Makefile.am (MODULES): Add it. * .dir-locals.el: Add indentation rules. --- .dir-locals.el | 4 ++ Makefile.am | 1 + guix/build/emacs-utils.scm | 92 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 guix/build/emacs-utils.scm diff --git a/.dir-locals.el b/.dir-locals.el index 64a680c59f..69c25cbe8f 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -29,6 +29,10 @@ (eval . (put 'call-with-compressed-output-port 'scheme-indent-function 2)) (eval . (put 'call-with-decompressed-port 'scheme-indent-function 2)) (eval . (put 'signature-case 'scheme-indent-function 1)) + (eval . (put 'emacs-batch-eval 'scheme-indent-function 0)) + (eval . (put 'emacs-batch-edit-file 'scheme-indent-function 1)) + (eval . (put 'emacs-substitute-sexps 'scheme-indent-function 1)) + (eval . (put 'emacs-substitute-variables 'scheme-indent-function 1)) (eval . (put 'syntax-parameterize 'scheme-indent-function 1)) (eval . (put 'with-monad 'scheme-indent-function 1)) diff --git a/Makefile.am b/Makefile.am index 6695e7e5b7..eab126acee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -73,6 +73,7 @@ MODULES = \ guix/build/install.scm \ guix/build/activation.scm \ guix/build/syscalls.scm \ + guix/build/emacs-utils.scm \ guix/packages.scm \ guix/snix.scm \ guix/scripts/download.scm \ diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm new file mode 100644 index 0000000000..10ef3c8d0f --- /dev/null +++ b/guix/build/emacs-utils.scm @@ -0,0 +1,92 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2014 Mark H Weaver +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix build emacs-utils) + #:export (%emacs + emacs-batch-eval + emacs-batch-edit-file + emacs-substitute-sexps + emacs-substitute-variables)) + +;;; Commentary: +;;; +;;; Tools to programmatically edit files using Emacs, +;;; e.g. to replace entire s-expressions in elisp files. +;;; +;;; Code: + +(define %emacs + ;; The `emacs' command. + (make-parameter "emacs")) + +(define (emacs-batch-eval expr) + "Run Emacs in batch mode, and execute the elisp code EXPR." + (unless (zero? (system* (%emacs) "--quick" "--batch" + (format #f "--eval=~S" expr))) + (error "emacs-batch-eval failed!" expr))) + +(define (emacs-batch-edit-file file expr) + "Load FILE in Emacs using batch mode, and execute the elisp code EXPR." + (unless (zero? (system* (%emacs) "--quick" "--batch" + (string-append "--visit=" file) + (format #f "--eval=~S" expr))) + (error "emacs-batch-edit-file failed!" file expr))) + +(define-syntax emacs-substitute-sexps + (syntax-rules () + "Substitute the S-expression immediately following the first occurrence of +LEADING-REGEXP by the string returned by REPLACEMENT in FILE. For example: + + (emacs-substitute-sexps \"w3m.el\" + (\"defcustom w3m-command\" + (string-append w3m \"/bin/w3m\")) + (\"defvar w3m-image-viewer\" + (string-append imagemagick \"/bin/display\"))) + +This replaces the default values of the `w3m-command' and `w3m-image-viewer' +variables declared in `w3m.el' with the results of the `string-append' calls +above. Note that LEADING-REGEXP uses Emacs regexp syntax." + ((emacs-substitute-sexps file (leading-regexp replacement) ...) + (emacs-batch-edit-file file + `(progn (progn (goto-char (point-min)) + (re-search-forward ,leading-regexp) + (kill-sexp) + (insert " ") + (insert ,(format #f "~S" replacement))) + ... + (basic-save-buffer)))))) + +(define-syntax emacs-substitute-variables + (syntax-rules () + "Substitute the default value of VARIABLE by the string returned by +REPLACEMENT in FILE. For example: + + (emacs-substitute-variables \"w3m.el\" + (\"w3m-command\" (string-append w3m \"/bin/w3m\")) + (\"w3m-image-viewer\" (string-append imagemagick \"/bin/display\"))) + +This replaces the default values of the `w3m-command' and `w3m-image-viewer' +variables declared in `w3m.el' with the results of the `string-append' calls +above." + ((emacs-substitute-variables file (variable replacement) ...) + (emacs-substitute-sexps file + ((string-append "(def[a-z]+[[:space:]\n]+" variable "\\>") + replacement) + ...)))) + +;;; emacs-utils.scm ends here