u
[emacs-helper.git] / eh-guix.el
blobcfac5c33cc1ee934dbdcf5b9f94b69cb7f555eae
1 ;;; eh-guix.el --- Tumashu's emacs configuation -*- lexical-binding: t; -*-
3 ;; * Header
4 ;; Copyright (c) 2011-2019, Feng Shu
6 ;; Author: Feng Shu <tumashu@163.com>
7 ;; URL: https://github.com/tumashu/emacs-helper
8 ;; Version: 0.0.1
10 ;; This file is not part of GNU Emacs.
12 ;;; License:
14 ;; This program is free software; you can redistribute it and/or
15 ;; modify it under the terms of the GNU General Public License
16 ;; as published by the Free Software Foundation; either version 3
17 ;; of the License, or (at your option) any later version.
19 ;; This program is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
29 ;;; Commentary:
31 ;; This emacs config will set a basic guix develop environment for new
32 ;; guix developer, it deal with guile %load-path with the help of
33 ;; GUIX_PACKAGE_PATH environment and 'guix repl' command.
35 ;; ** When it will useful?
37 ;; 1. You just use guile to develop guix and do not develop other
38 ;; projects.
39 ;; 2. You use 'guix pull' to update guix and other channels
40 ;; frequently, and do not like to deal with guile %load-path manually.
41 ;; 3. You just edit your own guix config or change ONE package file at
42 ;; a time in guix.git, this package file is relatively independent.
43 ;; 4. You do not ADD a new scm file to guix.git.
45 ;; ** How to start?
47 ;; 1. Load this config to emacs
48 ;; 2. Open guix file, for example: emacs-xyz.scm in guix.git.
49 ;; 3. M-x: geiser
50 ;; 4. Type 'C-c . u' key to use current guix module.
51 ;; 5. Type 'C-c C-b' to geiser-eval-buffer current buffer.
52 ;; 6. Edit... type 'C-M-x' or 'C-x C-e' to see result... edit again ...
54 ;;; Code:
55 (require 'geiser)
56 (require 'geiser-guile)
57 (require 'guix)
58 (require 'magit)
59 (require 'guix-devel)
61 ;; ** Enable guix-devel-mode
62 (add-hook 'scheme-mode-hook #'guix-devel-mode)
64 ;; ** Let geiser-guile use guix repl.
65 (defun eh-guix-get-guile-load-path ()
66 "Get guile load-path from GUIX_PACKAGE_PATH environment."
67 (when-let* ((path-str (getenv "GUIX_PACKAGE_PATH"))
68 (length (> (length path-str) 0))
69 (paths (split-string path-str ":")))
70 (mapcan (lambda (path)
71 (list "-L" (substitute-in-file-name path)))
72 paths)))
74 (setq geiser-guile-binary
75 `("guix" "repl"
76 ,@(eh-guix-get-guile-load-path)))
78 ;; ** Do not auto load paths to guile %load-path.
79 (defun eh-geiser-guile--startup (remote)
80 "Advice function of `geiser-guile--startup'.
81 Do not deal with `geiser-guile-load-path'."
82 (geiser-guile--set-up-error-links)
83 (let ((geiser-log-verbose t))
84 (when (or geiser-guile--conn-address remote)
85 (geiser-guile--set-geiser-load-path))
86 (geiser-guile--set-up-declarative-modules)
87 (geiser-guile--set-up-backtrace)
88 (geiser-eval--send/wait ",use (geiser emacs)\n'done")
89 (geiser-eval--send/wait ",use (guix)\n'done")
90 (geiser-eval--send/wait ",use (guix gexp)\n'done")
91 (geiser-eval--send/wait ",use (guix store)\n'done")
92 (geiser-eval--send/wait ",use (guix packages)\n'done")
93 (geiser-eval--send/wait ",use (guix derivations)\n'done")
94 (geiser-guile-update-warning-level)))
96 (defun eh-geiser-guile--parameters (orig-func &rest args)
97 "Advice function of `geiser-guile--parameters'.
98 Do not handle `geiser-guile-load-path'."
99 (let ((geiser-guile-load-path nil))
100 (apply orig-func args)))
102 ;; NOTE: geiser and geiser-guile will auto add project path,
103 ;; `geiser-guile-load-path' in dir-local.el and path of current-buffer
104 ;; to guile %load-path, this could lead to potential confusion for
105 ;; guix new developer. DISABLE THIS FEATURE, we just use
106 ;; GUIX_PACKAGE_PATH environment and 'guix repl' to handle %load-path.
107 (setq geiser-repl-add-project-paths nil)
108 (advice-add 'geiser-guile--startup :override #'eh-geiser-guile--startup)
109 (advice-add 'geiser-guile--parameters :around #'eh-geiser-guile--parameters)
111 ;; ** Get guix checkout directory.
112 (defun eh-guix-dir ()
113 "Get guix checkout directory created by guix pull."
114 (when-let* ((dir (expand-file-name "~/.cache/guix/checkouts/"))
115 (directory-p (file-directory-p dir)))
116 (file-name-as-directory
117 (cl-find-if
118 (lambda (dir)
119 (file-exists-p
120 (expand-file-name "guix.scm" dir)))
121 (directory-files dir t)))))
123 ;; ** Load guix copyright.el
124 (when-let* ((dir (eh-guix-dir))
125 (file (expand-file-name "etc/copyright.el" dir))
126 (exists-p (file-exists-p file)))
127 (load-file file)
128 ;; (add-hook 'after-save-hook 'copyright-update)
129 (defvar copyright-names-regexp)
130 (setq copyright-names-regexp
131 (format "%s <%s>" user-full-name user-mail-address)))
133 ;; ** Load guix tempel snippets.
134 (when-let* ((dir (eh-guix-dir))
135 (path (expand-file-name "etc/snippets/tempel/*" dir)))
136 (defvar tempel-path)
137 (add-to-list 'tempel-path path))
139 ;; * Footer
140 (provide 'eh-guix)
142 ;;; eh-guix.el ends here