Last active
January 14, 2017 02:03
-
-
Save FrancisMurillo/65d639fb8e7cac30c99f058d7586aabd to your computer and use it in GitHub Desktop.
Projectile Project Loader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(with-eval-after-load 'projectile | |
(defconst fn/project-file ".project.el" | |
"Project configuration file") | |
(defconst fn/project-local-file ".project-locals.el" | |
"Project local setting file") | |
(defconst fn/project-init-files (list fn/project-file fn/project-local-file) | |
"Project init files") | |
(defun fn/load-project-file () | |
"Loads the `fn/project-file' for a project. | |
This is run once after the project is loaded signifying project setup." | |
(interactive) | |
(when (projectile-project-p) | |
(lexical-let* ((current-project-root (projectile-project-root)) | |
(project-init-file (expand-file-name fn/project-file current-project-root))) | |
(when (file-exists-p project-init-file) | |
(message "Loading project init file for %s" (projectile-project-name)) | |
(condition-case ex | |
(load project-init-file t) | |
('error | |
(message | |
"There was an error loading %s: %s" | |
project-init-file | |
(error-message-string ex)))))))) | |
(defun fn/load-project-local-file () | |
"Loads the `fn/project-local-file' for a project. | |
This is run for every time a file in a project is opened signifying per-file setup." | |
(interactive) | |
(when (projectile-project-p) | |
(let* ((current-project-root (projectile-project-root)) | |
(project-local-init-file (expand-file-name fn/project-local-file current-project-root))) | |
(when (and (file-exists-p project-local-init-file) | |
(not (member (buffer-file-name) fn/project-init-files))) | |
(message | |
"Loading project local file for %s on %s" | |
(projectile-project-name) | |
(buffer-name)) | |
(condition-case ex | |
(load project-local-init-file t) | |
('error | |
(message | |
"There was an error loading %s: %s" | |
project-local-init-file | |
(error-message-string ex)))))))) | |
;; Safety Loader | |
(defvar fn/checked-projects (list) | |
"Projects that are trusted with loading `fn/project-init-files' or not.") | |
(defvar fn/loaded-projects (list) | |
"Projects that have been loaded by `fn/load-project-file'.") | |
(defun fn/safe-project-p (project-root) | |
"Check if PROJECT-ROOT can be trusted." | |
(lexical-let* ((last-modification-time | |
(file-attribute-modification-time (file-attributes project-root))) | |
(safe-project-properties | |
(or (cdr (assoc project-root fn/checked-projects)) | |
(lexical-let* ((base-properties | |
(list :last-modification-time last-modification-time | |
:project-root project-root)) | |
(trusted | |
(yes-or-no-p | |
(format "Do you ultimately trust the project at %s?" project-root))) | |
(new-properties | |
(plist-put base-properties :trusted trusted))) | |
new-properties)))) | |
(prog1 | |
(plist-get safe-project-properties :trusted) | |
(add-to-list 'fn/checked-projects | |
(cons project-root safe-project-properties))))) | |
(defun fn/safe-load-project-file () | |
"Safety wrapper around `fn/load-project-file' with `fn/safe-project-p'." | |
(when (projectile-project-p) | |
(lexical-let ((project-root (projectile-project-root)) | |
(project-name (projectile-project-name))) | |
(when (not (member project-root fn/loaded-projects)) | |
(if (not (fn/safe-project-p project-root)) | |
(message "Project script for %s is not trusted." project-name) | |
(fn/load-project-file) | |
(add-to-list 'fn/loaded-projects project-root)))))) | |
(defun fn/safe-load-project-local-file () | |
"Safety wrapper around `fn/load-project-local-file' with `fn/safe-project-p'." | |
(when (projectile-project-p) | |
(lexical-let ((project-root (projectile-project-root)) | |
(project-name (projectile-project-name))) | |
(if (not (fn/safe-project-p project-root)) | |
(message "Project local script for %s is not trusted." project-name) | |
(fn/load-project-local-file))))) | |
;; Project root script should run before project file script | |
(add-hook 'find-file-hook #'fn/safe-load-project-file t) | |
(add-hook 'dired-mode-hook #'fn/safe-load-project-file t) | |
(add-hook 'find-file-hook #'fn/safe-load-project-local-file t) | |
(add-hook 'dired-mode-hook #'fn/safe-load-project-local-file t)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment