;;; projectile-direnv.el --- Set environment variables from .envrc -*- lexical-binding: t; -*- ;; Copyright (C) 2016 Free Software Foundation, Inc. ;; Author: Christian Romney ;; 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 . ;;; 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