82 lines
3.2 KiB
EmacsLisp
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
|