Commit | Line | Data |
---|---|---|
cb85c0d8 EL |
1 | ;;; ede/auto.el --- Autoload features for EDE |
2 | ||
49f70d46 | 3 | ;; Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc. |
cb85c0d8 EL |
4 | |
5 | ;; Author: Eric M. Ludlam <zappo@gnu.org> | |
6 | ||
7 | ;; This file is part of GNU Emacs. | |
8 | ||
9 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
10 | ;; it under the terms of the GNU General Public License as published by | |
11 | ;; the Free Software Foundation, either version 3 of the License, or | |
12 | ;; (at your option) any later version. | |
13 | ||
14 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
21 | ||
22 | ;;; Commentary: | |
23 | ;; | |
24 | ;; EDE Autoloads are a way to refer to different project types without | |
25 | ;; loading those projects into Emacs. | |
26 | ;; | |
27 | ;; These routines are used to detect a project in a filesystem before | |
28 | ;; handing over control to the usual EDE project system. | |
29 | ||
30 | ;;; Code: | |
31 | ||
32 | (require 'eieio) | |
33 | ||
34 | (defclass ede-project-autoload () | |
35 | ((name :initarg :name | |
36 | :documentation "Name of this project type") | |
37 | (file :initarg :file | |
38 | :documentation "The lisp file belonging to this class.") | |
39 | (proj-file :initarg :proj-file | |
40 | :documentation "Name of a project file of this type.") | |
41 | (proj-root :initarg :proj-root | |
42 | :type function | |
43 | :documentation "A function symbol to call for the project root. | |
44 | This function takes no arguments, and returns the current directories | |
45 | root, if available. Leave blank to use the EDE directory walking | |
46 | routine instead.") | |
47 | (initializers :initarg :initializers | |
48 | :initform nil | |
49 | :documentation | |
50 | "Initializers passed to the project object. | |
51 | These are used so there can be multiple types of projects | |
52 | associated with a single object class, based on the initilizeres used.") | |
53 | (load-type :initarg :load-type | |
54 | :documentation "Fn symbol used to load this project file.") | |
55 | (class-sym :initarg :class-sym | |
56 | :documentation "Symbol representing the project class to use.") | |
57 | (new-p :initarg :new-p | |
58 | :initform t | |
59 | :documentation | |
60 | "Non-nil if this is an option when a user creates a project.") | |
a62d5ee1 EL |
61 | (safe-p :initarg :safe-p |
62 | :initform t | |
63 | :documentation | |
64 | "Non-nil if the project load files are \"safe\". | |
65 | An unsafe project is one that loads project variables via Emacs | |
66 | Lisp code. A safe project is one that loads project variables by | |
67 | scanning files without loading Lisp code from them.") | |
cb85c0d8 EL |
68 | ) |
69 | "Class representing minimal knowledge set to run preliminary EDE functions. | |
70 | When more advanced functionality is needed from a project type, that projects | |
71 | type is required and the load function used.") | |
72 | ||
73 | (defvar ede-project-class-files | |
74 | (list | |
75 | (ede-project-autoload "edeproject-makefile" | |
76 | :name "Make" :file 'ede/proj | |
77 | :proj-file "Project.ede" | |
78 | :load-type 'ede-proj-load | |
a62d5ee1 EL |
79 | :class-sym 'ede-proj-project |
80 | :safe-p nil) | |
cb85c0d8 EL |
81 | (ede-project-autoload "edeproject-automake" |
82 | :name "Automake" :file 'ede/proj | |
83 | :proj-file "Project.ede" | |
84 | :initializers '(:makefile-type Makefile.am) | |
85 | :load-type 'ede-proj-load | |
a62d5ee1 EL |
86 | :class-sym 'ede-proj-project |
87 | :safe-p nil) | |
cb85c0d8 EL |
88 | (ede-project-autoload "automake" |
89 | :name "automake" :file 'ede/project-am | |
90 | :proj-file "Makefile.am" | |
91 | :load-type 'project-am-load | |
92 | :class-sym 'project-am-makefile | |
93 | :new-p nil)) | |
94 | "List of vectors defining how to determine what type of projects exist.") | |
95 | ||
a62d5ee1 EL |
96 | (put 'ede-project-class-files 'risky-local-variable t) |
97 | ||
cb85c0d8 EL |
98 | ;;; EDE project-autoload methods |
99 | ;; | |
100 | (defmethod ede-project-root ((this ede-project-autoload)) | |
101 | "If a project knows its root, return it here. | |
102 | Allows for one-project-object-for-a-tree type systems." | |
103 | nil) | |
104 | ||
105 | (defmethod ede-project-root-directory ((this ede-project-autoload) | |
106 | &optional file) | |
107 | "If a project knows its root, return it here. | |
108 | Allows for one-project-object-for-a-tree type systems. | |
109 | Optional FILE is the file to test. If there is no FILE, use | |
110 | the current buffer." | |
111 | (when (not file) | |
112 | (setq file default-directory)) | |
113 | (when (slot-boundp this :proj-root) | |
114 | (let ((rootfcn (oref this proj-root))) | |
115 | (when rootfcn | |
116 | (condition-case nil | |
117 | (funcall rootfcn file) | |
118 | (error | |
119 | (funcall rootfcn))) | |
120 | )))) | |
121 | ||
122 | (defmethod ede-dir-to-projectfile ((this ede-project-autoload) dir) | |
123 | "Return a full file name of project THIS found in DIR. | |
124 | Return nil if the project file does not exist." | |
125 | (let* ((d (file-name-as-directory dir)) | |
126 | (root (ede-project-root-directory this d)) | |
127 | (pf (oref this proj-file)) | |
128 | (f (cond ((stringp pf) | |
129 | (expand-file-name pf (or root d))) | |
130 | ((and (symbolp pf) (fboundp pf)) | |
131 | (funcall pf (or root d))))) | |
132 | ) | |
133 | (when (and f (file-exists-p f)) | |
134 | f))) | |
135 | ||
a62d5ee1 EL |
136 | (defmethod ede-auto-load-project ((this ede-project-autoload) dir) |
137 | "Load in the project associated with THIS project autoload description. | |
138 | THIS project description should be valid for DIR, where the project will | |
139 | be loaded." | |
140 | ;; Last line of defense: don't load unsafe projects. | |
141 | (when (not (or (oref this :safe-p) | |
142 | (ede-directory-safe-p dir))) | |
143 | (error "Attempt to load an unsafe project (bug elsewhere in EDE)")) | |
144 | ;; Things are good - so load the project. | |
145 | (let ((o (funcall (oref this load-type) dir))) | |
146 | (when (not o) | |
147 | (error "Project type error: :load-type failed to create a project")) | |
148 | (ede-add-project-to-global-list o))) | |
cb85c0d8 EL |
149 | |
150 | (provide 'ede/auto) | |
151 | ||
152 | ;;; ede/auto.el ends here |