guix-devel
[Top][All Lists]
Advanced

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

[PATCHES] Add (guix build emacs-utils) and some Emacs packages


From: mhw
Subject: [PATCHES] Add (guix build emacs-utils) and some Emacs packages
Date: Tue, 12 Aug 2014 23:50:13 -0400

I've attached patches to add new packages for 'magit', 'paredit',
'emacs-w3m', and 'emacs-wget'.  While working on these packages, I found
that I needed a way to substitute multi-line s-expressions in the elisp
code, in order to replace initializers for variables.

In particular, these patches arrange to initialize certain variables
containing pathnames and program names to absolute paths in the store.
Sometimes the original initializers are multi-line expressions that
search for the correct path using heuristics.

The approach I took was to create a new module (guix build emacs-utils)
containing utilities that use Emacs itself to perform the substitutions.

What do you think?

      Mark


>From ce477199a135eac797f03c86ce99595bc47affeb Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
Date: Sat, 2 Aug 2014 19:24:50 -0400
Subject: [PATCH 1/5] 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             |  3 ++
 Makefile.am                |  1 +
 guix/build/emacs-utils.scm | 84 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)
 create mode 100644 guix/build/emacs-utils.scm

diff --git a/.dir-locals.el b/.dir-locals.el
index 64a680c..16ec640 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -29,6 +29,9 @@
    (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-edit-file 'scheme-indent-function 1))
+   (eval . (put 'emacs-substitute-sexps 'scheme-indent-function 1))
+   (eval . (put 'emacs-substitute-vars '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 6695e7e..eab126a 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 0000000..e407d11
--- /dev/null
+++ b/guix/build/emacs-utils.scm
@@ -0,0 +1,84 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2014 Mark H Weaver <address@hidden>
+;;;
+;;; 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 <http://www.gnu.org/licenses/>.
+
+(define-module (guix build emacs-utils)
+  #:export (emacs-batch-edit-file
+            emacs-substitute-sexps
+            emacs-substitute-vars))
+
+;;; 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-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-vars
+  (syntax-rules ()
+    "Substitute the default value of VARIABLE by the string returned by
+REPLACEMENT in FILE.  For example:
+
+  (emacs-substitute-vars \"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-vars file (variable replacement) ...)
+     (emacs-substitute-sexps file
+       ((string-append "(def[a-z]+[[:space:]\n]+" variable "\\>")
+        replacement)
+       ...))))
+
+;;; emacs-utils.scm ends here
-- 
1.8.4

>From 3878daebbc09122a2c789984e5f822f51eb3c667 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
Date: Sat, 2 Aug 2014 22:20:23 -0400
Subject: [PATCH 2/5] gnu: Add magit.

* gnu/packages/emacs.scm (magit): New variable.
---
 gnu/packages/emacs.scm | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index a9cfa19..9149f9b 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Taylan Ulrich Bayirli/Kammer <address@hidden>
 ;;; Copyright © 2013 Ludovic Courtès <address@hidden>
+;;; Copyright © 2014 Mark H Weaver <address@hidden>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -34,6 +35,7 @@
   #:use-module (gnu packages image)
   #:use-module (gnu packages giflib)
   #:use-module (gnu packages linux)
+  #:use-module (gnu packages version-control)
   #:use-module ((gnu packages compression)
                 #:renamer (symbol-prefix-proc 'compression:))
   #:use-module (gnu packages xml)
@@ -152,3 +154,53 @@ of the stage in Geiser.  A bundle of Elisp shims 
orchestrates the dialog
 between the Scheme interpreter, Emacs and, ultimately, the schemer,
 giving her access to live metadata.")
     (license bsd-3)))
+
+(define-public magit
+  (package
+    (name "magit")
+    (version "1.2.0")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append 
"https://github.com/downloads/magit/magit/magit-";
+                                 version ".tar.gz"))
+             (sha256
+              (base32 
"1a8vvilhd5y5vmlpsh194qpl4qlg0a1brylfscxcacpfp0cmhlzg"))))
+    (build-system gnu-build-system)
+    (native-inputs `(("texinfo" ,texinfo)))
+    (inputs `(("emacs" ,emacs)
+              ("git" ,git)
+              ("git:gui" ,git "gui")))
+    (arguments
+     `(#:modules ((guix build gnu-build-system)
+                  (guix build utils)
+                  (guix build emacs-utils))
+       #:imported-modules ((guix build gnu-build-system)
+                           (guix build utils)
+                           (guix build emacs-utils))
+       #:tests? #f  ; no check target
+       #:phases
+       (alist-replace
+        'configure
+        (lambda* (#:key outputs #:allow-other-keys)
+          (let ((out (assoc-ref outputs "out")))
+            (substitute* "Makefile"
+              (("/usr/local") out)
+              (("/etc") (string-append out "/etc")))))
+        (alist-cons-before
+         'build 'patch-exec-paths
+         (lambda* (#:key inputs #:allow-other-keys)
+           (let ((git (assoc-ref inputs "git"))
+                 (git:gui (assoc-ref inputs "git:gui")))
+             (emacs-substitute-vars "magit.el"
+               ("magit-git-executable" (string-append git "/bin/git"))
+               ("magit-gitk-executable" (string-append git:gui "/bin/gitk")))))
+         %standard-phases))))
+    (home-page "http://magit.github.io/";)
+    (synopsis "Emacs interface for the Git version control system")
+    (description
+     "With Magit, you can inspect and modify your Git repositories with Emacs.
+You can review and commit the changes you have made to the tracked files, for
+example, and you can browse the history of past changes.  There is support for
+cherry picking, reverting, merging, rebasing, and other common Git
+operations.")
+    (license gpl3+)))
-- 
1.8.4

>From cc12fa6243da5a61f1421d1d3dfe64af2cf76102 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
Date: Sat, 2 Aug 2014 20:01:48 -0400
Subject: [PATCH 3/5] gnu: Add paredit.

* gnu/packages/emacs.scm (paredit): New variable.
---
 gnu/packages/emacs.scm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index 9149f9b..07fe73a 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -23,6 +23,7 @@
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix build-system gnu)
+  #:use-module (guix build-system trivial)
   #:use-module (gnu packages)
   #:use-module (gnu packages gtk)
   #:use-module (gnu packages ncurses)
@@ -155,6 +156,51 @@ between the Scheme interpreter, Emacs and, ultimately, the 
schemer,
 giving her access to live metadata.")
     (license bsd-3)))
 
+(define-public paredit
+  (package
+    (name "paredit")
+    (version "23")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "http://mumble.net/~campbell/emacs/paredit-";
+                                 version ".el"))
+             (sha256
+              (base32 
"1np882jzvxckljx3cjz4absyzmc5hw65cs21sjmbic82163m9lf8"))))
+    (build-system trivial-build-system)
+    (inputs `(("emacs" ,emacs)))
+    (arguments
+     `(#:modules ((guix build utils))
+       #:builder
+       (begin
+         (use-modules (guix build utils))
+
+         (let* ((emacs (string-append (assoc-ref %build-inputs "emacs")
+                                      "/bin/emacs"))
+                (source (assoc-ref %build-inputs "source"))
+                (lisp-dir (string-append %output
+                                         "/share/emacs/site-lisp"))
+                (target (string-append lisp-dir "/paredit.el")))
+           (mkdir-p lisp-dir)
+           (copy-file source target)
+           (with-directory-excursion lisp-dir
+             (unless (zero? (system*
+                             emacs "--quick" "--batch"
+                             (format #f "--eval=~S"
+                                     '(byte-compile-file "paredit.el"))))
+               (error "failed to compile paredit.el!")))))))
+    (home-page "http://mumble.net/~campbell/emacs/paredit/";)
+    (synopsis "Emacs minor mode for editing parentheses")
+    (description
+     "ParEdit (paredit.el) is a minor mode for performing structured editing
+of S-expression data.  The typical example of this would be Lisp or Scheme
+source code.
+
+ParEdit helps **keep parentheses balanced** and adds many keys for moving
+S-expressions and moving around in S-expressions.  Its behavior can be jarring
+for those who may want transient periods of unbalanced parentheses, such as
+when typing parentheses directly or commenting out code line by line.")
+    (license gpl3+)))
+
 (define-public magit
   (package
     (name "magit")
-- 
1.8.4

>From 77cbe9246651b759d8ff6bb93b06fd523668fb29 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
Date: Thu, 24 Jul 2014 11:38:42 -0400
Subject: [PATCH 4/5] gnu: Add emacs-w3m.

* gnu/packages/emacs.scm (emacs-w3m): New variable.
---
 gnu/packages/emacs.scm | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index 07fe73a..9e8a793 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -37,6 +37,9 @@
   #:use-module (gnu packages giflib)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages version-control)
+  #:use-module (gnu packages imagemagick)
+  #:use-module (gnu packages w3m)
+  #:use-module (gnu packages autotools)
   #:use-module ((gnu packages compression)
                 #:renamer (symbol-prefix-proc 'compression:))
   #:use-module (gnu packages xml)
@@ -250,3 +253,77 @@ example, and you can browse the history of past changes.  
There is support for
 cherry picking, reverting, merging, rebasing, and other common Git
 operations.")
     (license gpl3+)))
+
+
+;;;
+;;; Web browsing.
+;;;
+
+(define-public emacs-w3m
+  (package
+    (name "emacs-w3m")
+    (version "1.4.483+0.20120614")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "mirror://debian/pool/main/w/w3m-el/w3m-el_"
+                                 version ".orig.tar.gz"))
+             (sha256
+              (base32 
"0ms181gjavnfk79hhv5xl9llik4c6kj0w3c04kgyif8lcy2sxljx"))))
+    (build-system gnu-build-system)
+    (native-inputs `(("autoconf" ,autoconf)))
+    (inputs `(("w3m" ,w3m)
+              ("imagemagick" ,imagemagick)
+              ("emacs" ,emacs)))
+    (arguments
+     '(#:modules ((guix build gnu-build-system)
+                  (guix build utils)
+                  (guix build emacs-utils))
+       #:imported-modules ((guix build gnu-build-system)
+                           (guix build utils)
+                           (guix build emacs-utils))
+       #:configure-flags
+       (let ((out (assoc-ref %outputs "out")))
+         (list (string-append "--with-lispdir="
+                              out "/share/emacs/site-lisp")
+               (string-append "--with-icondir="
+                              out "/share/images/emacs-w3m")))
+       #:tests? #f  ; no check target
+       #:phases
+       (alist-cons-before
+        'configure 'pre-configure
+        (lambda _
+          (zero? (system* "autoconf")))
+        (alist-cons-before
+         'build 'patch-exec-paths
+         (lambda* (#:key inputs outputs #:allow-other-keys)
+          (let ((out (assoc-ref outputs "out"))
+                (w3m (assoc-ref inputs "w3m"))
+                (imagemagick (assoc-ref inputs "imagemagick"))
+                (coreutils (assoc-ref inputs "coreutils")))
+            (emacs-substitute-vars "w3m.el"
+              ("w3m-command" (string-append w3m "/bin/w3m"))
+              ("w3m-touch-command" (string-append coreutils "/bin/touch"))
+              ("w3m-image-viewer" (string-append imagemagick "/bin/display"))
+              ("w3m-icon-directory" (string-append out
+                                                   "/share/images/emacs-w3m")))
+            (emacs-substitute-vars "w3m-image.el"
+              ("w3m-imagick-convert-program" (string-append imagemagick
+                                                            "/bin/convert"))
+              ("w3m-imagick-identify-program" (string-append imagemagick
+                                                             "/bin/identify")))
+            #t))
+         (alist-replace
+          'install
+          (lambda* (#:key outputs #:allow-other-keys)
+            (and (zero? (system* "make" "install" "install-icons"))
+                 (with-directory-excursion
+                     (string-append (assoc-ref outputs "out")
+                                    "/share/emacs/site-lisp")
+                   (for-each delete-file '("ChangeLog" "ChangeLog.1"))
+                   #t)))
+          %standard-phases)))))
+    (home-page "http://emacs-w3m.namazu.org/";)
+    (synopsis "A simple web browser for emacs, based on w3m.")
+    (description
+     "emacs-w3m is an emacs interface for the w3m web browser.")
+    (license gpl2+)))
-- 
1.8.4

>From d54e2c12e481f711ff9c533f9dcdd4570e070897 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
Date: Sun, 27 Jul 2014 16:37:13 -0400
Subject: [PATCH 5/5] gnu: Add emacs-wget.

* gnu/packages/emacs.scm (emacs-wget): New variable.
---
 gnu/packages/emacs.scm | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index 9e8a793..b5300e2 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -39,6 +39,7 @@
   #:use-module (gnu packages version-control)
   #:use-module (gnu packages imagemagick)
   #:use-module (gnu packages w3m)
+  #:use-module (gnu packages wget)
   #:use-module (gnu packages autotools)
   #:use-module ((gnu packages compression)
                 #:renamer (symbol-prefix-proc 'compression:))
@@ -327,3 +328,44 @@ operations.")
     (description
      "emacs-w3m is an emacs interface for the w3m web browser.")
     (license gpl2+)))
+
+(define-public emacs-wget
+  (package
+    (name "emacs-wget")
+    (version "0.5.0")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "mirror://debian/pool/main/w/wget-el/wget-el_"
+                                 version ".orig.tar.gz"))
+             (sha256
+              (base32 
"10byvyv9dk0ib55gfqm7bcpxmx2qbih1jd03gmihrppr2mn52nff"))))
+    (build-system gnu-build-system)
+    (inputs `(("wget" ,wget)
+              ("emacs" ,emacs)))
+    (arguments
+     '(#:modules ((guix build gnu-build-system)
+                  (guix build utils)
+                  (guix build emacs-utils))
+       #:imported-modules ((guix build gnu-build-system)
+                           (guix build utils)
+                           (guix build emacs-utils))
+       #:tests? #f  ; no check target
+       #:phases
+       (alist-replace
+        'configure
+        (lambda* (#:key outputs #:allow-other-keys)
+          (substitute* "Makefile"
+            (("/usr/local") (assoc-ref outputs "out"))
+            (("/site-lisp/emacs-wget") "/site-lisp")))
+        (alist-cons-before
+         'build 'patch-exec-paths
+         (lambda* (#:key inputs outputs #:allow-other-keys)
+           (let ((wget (assoc-ref inputs "wget")))
+             (emacs-substitute-vars "wget.el"
+               ("wget-command" (string-append wget "/bin/wget")))))
+         %standard-phases))))
+    (home-page "http://www.emacswiki.org/emacs/EmacsWget";)
+    (synopsis "A simple file downloader for emacs, based on wget.")
+    (description
+     "emacs-wget is an emacs interface for the wget file downloader.")
+    (license gpl2+)))
-- 
1.8.4


reply via email to

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