my-emacs-d/elpa/projectile-direnv-20160305..../projectile-direnv.el

82 lines
3.2 KiB
EmacsLisp

;;; projectile-direnv.el --- Set environment variables from .envrc -*- lexical-binding: t; -*-
;; Copyright (C) 2016 Free Software Foundation, Inc.
;; Author: Christian Romney <crommney@pointslope.com>
;; URL: https://github.com/christianromney/projectile-direnv
;; Package-Version: 20160305.1738
;; Keywords: convenience
;; Version: 0.1.0
;; Package-Requires: ((emacs "24") (s "1.11.0") (dash "2.12.0") (projectile "0.13.0"))
;; This program 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.
;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; I want to launch Emacs as a GUI and have it automatically
;; set the same environment variables that direnv sets for me
;; at the shell when I am in a Projectile project.
;;
;; See README.org for more info.
;;
;;; Code:
(require 's)
(require 'dash)
(require 'projectile)
(defvar projectile-direnv-envrc nil
"Contains the path to the last loaded .envrc")
(defun projectile-direnv-parse-export (line)
"Parses a single line of the form export VAR=VAL into a cons
cell where the car is the var name and the cdr is its value."
(let* ((parts (s-split "=" line))
(varname (car (last (s-split " " (car parts)))))
(varval (car (last parts))))
(cons varname varval)))
(defun projectile-direnv-read-file-as-string (filename)
"Returns a the file's contents as a string"
(with-temp-buffer
(insert-file-contents filename)
(buffer-string)))
(defun projectile-direnv-set-env-var (pair)
"Sets an environment variable. Expects a pair of (VARNAME . VALUE)"
(setenv (car pair) (cdr pair)))
(defun projectile-direnv-list-exports (exports)
"Returns a string of the form '+VAR1 +VAR2' listing the exported envvars"
(s-join " " (-map (lambda (e) (s-append (car e) "+")) exports)))
(defun projectile-direnv-export-variables ()
"Reads a .envrc file in the Projectile project root, and sets
environment variables for any defined exports"
(interactive)
(when (projectile-project-p)
(let ((envrc (expand-file-name ".envrc" (projectile-project-root))))
(when (and (file-exists-p envrc)
(not (string= envrc projectile-direnv-envrc)))
(let* ((contents (projectile-direnv-read-file-as-string envrc))
(lines (s-split "\n" contents))
(exports (-filter (lambda (l) (s-starts-with? "export" l)) lines))
(envvars (-map #'projectile-direnv-parse-export exports)))
(setq projectile-direnv-envrc envrc)
(-each envvars #'projectile-direnv-set-env-var)
(message "projectile-direnv: export %s" (projectile-direnv-list-exports envvars)))))))
(provide 'projectile-direnv)
;;; projectile-direnv.el ends here