1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;; eproject.el --- project workspaces for emacs
5 ;; Copyright (C) 2008 grischka
7 ;; Author: grischka -- grischka@users.sourceforge.net
8 ;; Created: 24 Jan 2008
11 ;; This program is free software, released under the GNU General
12 ;; Public License (GPL, version 2). For details see:
14 ;; http://www.fsf.org/licenses/gpl.html
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23 ;; There is a global file
24 (defun prj-globalfile ()
25 (expand-file-name (concat user-emacs-directory
"eproject.lst"))
28 ;; with the list of all projects
31 ;; and the project that was open in the last session (if any)
32 (defvar prj-last-open nil
)
34 ;; and the frame coords from last session
35 (defvar prj-frame-pos nil
)
37 ;; eproject version that created the config file
38 (defvar prj-version nil
)
40 ;; Here is a function to reset these
42 (setq prj-version nil
)
44 (setq prj-last-open nil
)
45 (setq prj-frame-pos nil
)
48 ;; Each project has a directory
49 (defvar prj-directory
)
51 ;; with a configuration files in it
52 (defun prj-localfile ()
53 (expand-file-name "eproject.cfg" prj-directory
)
64 ;; an alist of settings
70 ;; a list of utility functions (feature incomplete)
71 (defvar prj-functions nil
)
73 ;; directory to run commands, default to prj-directory
74 (defvar prj-directory-run
)
76 ;; Here are some default tools for new projects,
77 ;; (which you might want to adjust to your needs)
79 (defun prj-default-config ()
80 (setq prj-tools
(copy-tree '(
82 ("Clean" "make clean" "C-f9")
83 ("Run" "echo run what" "f8")
84 ("Stop" "-e eproject-killtool" "C-f8")
86 ("Configure" "./configure")
88 ("Explore Project" "nautilus --browser `pwd` &")
89 ("XTerm In Project" "xterm &")
93 ;; This defines the current project
96 ;; There is an internal list with generated functions
98 (defvar prj-tools-fns
)
100 ;; and a list with files removed from the project
101 (defvar prj-removed-files
)
103 ;; Here is a function to reset/close the project
105 (setq prj-version nil
)
106 (setq prj-current nil
)
107 (setq prj-directory nil
)
108 (setq prj-directory-run nil
)
110 (setq prj-removed-files nil
)
111 (setq prj-curfile nil
)
112 (setq prj-config nil
)
114 (setq prj-tools-fns nil
)
115 (prj-reset-functions)
119 (defun prj-reset-functions ()
120 (dolist (l prj-functions
)
121 (if (eq (car l
) 'setq
)
122 (makunbound (cadr l
))
123 (fmakunbound (cadr l
))
125 (setq prj-functions nil
)
128 (defun prj-set-functions (s)
129 (prj-reset-functions)
130 (setq prj-functions s
)
131 (dolist (l s
) (eval l
))
134 ;; Some more variables
136 ;; the frame that exists on startup
137 (defvar prj-initial-frame nil
)
139 ;; this is put into minor-mode-alist
140 (defvar eproject-mode t
)
142 ;; where this file is in
143 (defvar eproject-directory
)
145 ;; eproject version that created the files
146 (defvar eproject-version
"0.2")
150 (defun eproject-setup-toggle () (interactive))
151 (defun eproject-setup-quit () (interactive))
152 (defun prj-config-get-result (s))
153 (defun prj-config-reset ())
154 (defun prj-config-print ())
155 (defun prj-config-parse ())
158 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
161 (defun prj-del-list (l e
)
162 (let ((a (assoc (car e
) l
)))
167 (defun prj-add-list (l e
)
168 (nconc (prj-del-list l e
) (list e
))
171 (defun prj-next-file (l e
)
172 (let ((a (assoc (car e
) l
)))
175 (if (cdr l
) (cadr l
) a
)
178 (defun prj-prev-file (l e
)
179 (let ((a (assoc (car e
) l
)) (p l
))
181 (while (and l
(null (eq (car l
) a
)))
187 ;; replace a closed file, either by the previous or the next.
188 (defun prj-otherfile (l f
)
189 (let ((n (prj-prev-file l f
)))
191 (setq n
(prj-next-file l f
))
197 (defun caddr (l) (car (cddr l
)))
199 ;; make relative path, but only up to the second level of ..
200 (defun prj-relative-path (f)
201 (let ((r (file-relative-name f prj-directory
)))
202 (if (string-match "^\\.\\.[/\\]\\.\\.[/\\]\\.\\.[/\\]" r
)
207 ;; friendly truncate filename
208 (defun prj-shortname (s)
209 (let ((l (length s
)) (x 30) n
)
213 (setq n
(length (file-name-nondirectory s
)))
214 (if (< n l
) (setq n
(1+ n
)))
217 (concat (substring s
0 (- x n
)) "..." (substring s
(- n
)))
220 (concat (substring s
0 x
) "...")
223 (concat "..." (substring s
(- n
) (- (- x
3) n
)) "...")
226 (defun prj-settitle ()
227 (modify-frame-parameters
231 (format "emacs - %s" (car prj-current
))
234 (defun eproject-addon (f)
235 (concat eproject-directory f
)
238 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
239 ;; Write configuration to file
241 (defun prj-print-list (s fp
)
243 (setq v
(list 'setq s
244 (if (and (atom v
) (null (and (symbolp v
) v
)))
249 (pp v fp
) (princ "\n" fp
)
252 (defun prj-create-file (filename)
253 (let ((fp (generate-new-buffer filename
)))
254 (princ ";; -*- mode: Lisp; -*-\n\n" fp
)
257 (defun prj-close-file (fp)
258 (with-current-buffer fp
260 (write-region 1 (point-max) (buffer-name fp
) nil
0)
266 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
267 ;; Load/Save global project list and initial frame sizes
269 (defun prj-loadlist ()
271 (load (prj-globalfile) t t
)
272 (setq prj-version eproject-version
)
275 (defun prj-get-frame-pos (f)
278 (lambda (parm) (cons parm
(frame-parameter f parm
)))
279 '(top left width height
)
282 (defun prj-savelist ()
283 (let ((g (prj-globalfile))
286 (unless (file-exists-p g
)
287 (make-directory (file-name-directory g
) t
)
289 (setq prj-last-open
(car prj-current
))
290 (when (frame-live-p prj-initial-frame
)
291 (setq prj-frame-pos
(prj-get-frame-pos prj-initial-frame
))
293 (setq fp
(prj-create-file g
))
295 (prj-print-list 'prj-version fp
)
296 (prj-print-list 'prj-list fp
)
297 (prj-print-list 'prj-last-open fp
)
298 (prj-print-list 'prj-frame-pos fp
)
302 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
303 ;; Load/Save local per-project configuration file
305 (defun prj-update-config ()
306 (setq prj-directory-run
307 (file-name-as-directory
309 (or (prj-getconfig "run-directory") ".")
314 (defun prj-loadconfig (a)
319 (file-name-as-directory
320 (expand-file-name (cadr a
))
323 (when (file-exists-p (setq lf
(prj-localfile)))
326 (or (assoc prj-curfile prj-files
)
330 (if (setq e
(prj-getconfig "project-name"))
332 (prj-setconfig "project-name" (car a
))
335 (prj-set-functions prj-functions
)
336 (setq prj-version eproject-version
)
339 (defun prj-saveconfig ()
341 (let (w c b path files
)
343 (setq w
(selected-window))
344 (setq c
(window-buffer w
))
345 (dolist (f prj-files
)
346 (setq path
(expand-file-name (car f
) prj-directory
))
347 (cond ((setq b
(get-file-buffer path
))
348 (set-window-buffer w b t
)
350 (line-number-at-pos (window-start w
))
351 (line-number-at-pos (window-point w
))
358 (set-window-buffer w c t
)
360 (let ((fp (prj-create-file (prj-localfile)))
361 (prj-curfile (car prj-curfile
))
362 (prj-files (nreverse files
))
365 (prj-print-list 'prj-version fp
)
366 (prj-print-list 'prj-config fp
)
367 (prj-print-list 'prj-tools fp
)
368 (prj-print-list 'prj-files fp
)
369 (prj-print-list 'prj-curfile fp
)
370 (prj-print-list 'prj-functions fp
)
375 (defun prj-saveall ()
380 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
381 ;; The core functions: Open / Close / Add / Remove Project
383 (defun eproject-open (a)
384 "Open another project."
387 (or (prj-config-get-result 'p
)
388 (completing-read "Open Project: " (mapcar 'car prj-list
))
391 (let ((b (assoc a prj-list
)))
393 (error "No such project: %s" a
)
397 (setq a
(or (car (member a prj-list
)) a
))
398 (unless (eq a prj-current
)
399 (unless (file-directory-p (cadr a
))
400 (error "Error: No such directory: %s" (cadr a
))
402 (setq prj-list
(cons a
(delq a prj-list
)))
409 (unless (prj-edit-file prj-curfile
)
413 (defun eproject-close ()
414 "Close the current project."
422 (save-some-buffers nil
)
423 (eproject-killbuffers t
)
426 (or f
(prj-addhooks))
433 (defun eproject-killbuffers (&optional from-project
)
434 "If called interactively kills all buffers that
435 do not belong to project files"
438 (dolist (f prj-files
)
439 (setq b
(get-file-buffer (expand-file-name (car f
) prj-directory
)))
440 (if b
(setq a
(cons (list b
) a
)))
442 (dolist (b (buffer-list))
443 (when (eq (consp (assoc b a
)) from-project
)
447 (defun eproject-add (d)
448 "Add a new or existing project to the list."
451 (read-directory-name "Add project in directory: " prj-directory nil t
)
454 (setq d
(directory-file-name d
))
456 (when (= 0 (length d
))
457 (error "Error: Empty directory name.")
460 (setq n
(file-name-nondirectory d
))
466 (defun eproject-remove (a)
467 "Remove a project from the list."
470 (or (prj-config-get-result 'p
)
471 (completing-read "Remove project: " (mapcar 'car prj-list
))
474 (let ((b (assoc a prj-list
)))
476 (error "No such project: %s" a
)
482 (prog1 (y-or-n-p (format "Remove \"%s\"? " (car a
)))
485 (setq prj-list
(prj-del-list prj-list a
))
489 (defun eproject-save ()
490 "Save the project configuration to file."
497 (defun eproject-revert ()
498 "Reload the project configuration from file."
502 (prj-loadconfig prj-current
)
507 (defun eproject-addfile (f)
508 "Add a file to the current project."
512 (read-file-name "Add file to project: " nil nil t nil
)
514 (unless prj-current
(error "No project open"))
515 (let ((a (prj-insert-file f
(prj-config-get-result 'f
))))
517 (message "Added to project: %s" (car a
))
523 (defun eproject-removefile (a)
524 "Remove a file from the current project."
525 (interactive (prj-get-existing-file-1 "Remove file from project: "))
526 (setq a
(prj-get-existing-file-2 a
))
530 (defun eproject-visitfile (a)
531 "Visit a file from the current project."
532 (interactive (prj-get-existing-file-1 "Visit file: "))
533 (setq a
(prj-get-existing-file-2 a
))
537 (defun prj-get-existing-file-1 (msg)
540 (or (prj-config-get-result 'f
)
541 (completing-read msg
(mapcar 'car prj-files
))
544 (defun prj-get-existing-file-2 (a)
545 (unless prj-current
(error "No project open"))
548 (let ((b (assoc (prj-relative-path a
) prj-files
)))
549 (unless b
(error "No such file in project: %s" a
))
553 (defun eproject-help ()
554 "Show the eproject README."
556 (view-file (eproject-addon "eproject.txt"))
559 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
560 ;; Hook functions to track opening/closing files from emacs
562 (defun prj-addhooks ()
563 (add-hook 'kill-buffer-hook
'prj-kill-buffer-hook
)
564 (add-hook 'find-file-hook
'prj-find-file-hook
)
565 (add-hook 'window-configuration-change-hook
'prj-wcc-hook
)
568 (defun prj-removehooks ()
569 (remove-hook 'window-configuration-change-hook
'prj-wcc-hook
)
570 (remove-hook 'find-file-hook
'prj-find-file-hook
)
571 (remove-hook 'kill-buffer-hook
'prj-kill-buffer-hook
)
574 (defun prj-wcc-hook ()
575 (let* ((w (selected-window))
576 (b (window-buffer w
))
578 ;; (message "wcc-hook: %s" (prin1-to-string (list wcc-count w b n)))
579 (prj-register-buffer b
)
582 (defun prj-find-file-hook ()
586 (let* ((b ,(current-buffer))
587 (a (prj-register-buffer b
))
590 (with-current-buffer b
591 (rename-buffer (car a
) t
)
594 (defun prj-kill-buffer-hook ()
595 (let ((b (current-buffer)) a
)
596 (if (setq a
(rassq b prj-files
))
597 (prj-remove-file a t
)
598 (if (setq a
(rassq b prj-removed-files
))
599 (setq prj-removed-files
(delq a prj-removed-files
))
602 (defun prj-register-buffer (b)
604 (setq f
(buffer-file-name b
))
606 (setq a
(rassq b prj-files
))
608 (setq a
(prj-insert-file f nil t
))
611 (message "Added to project: %s" (car a
))
615 (when (and a
(null (eq a prj-curfile
)))
621 (defun prj-insert-file (f &optional after on-the-fly
)
622 (let ((r (prj-relative-path f
)) a m
)
623 (setq a
(assoc r prj-files
))
624 (unless (or a
(and on-the-fly
(assoc r prj-removed-files
)))
626 (setq m
(memq (or after prj-curfile
) prj-files
))
628 (setcdr m
(cons a
(cdr m
)))
629 (setq prj-files
(prj-add-list prj-files a
))
631 (setq prj-removed-files
(prj-del-list prj-removed-files a
))
635 (defun prj-remove-file (a &optional on-the-fly
)
636 (let ((n (prj-otherfile prj-files a
)) b
)
637 (setq prj-files
(prj-del-list prj-files a
))
638 (if (eq prj-curfile a
) (setq prj-curfile n
))
640 (setq prj-removed-files
(prj-add-list prj-removed-files a
))
641 (or (prj-config-print)
642 (prj-edit-file prj-curfile
)
646 (message "Removed from project: %s" (car a
))
649 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
652 (defun prj-edit-file (a)
655 (f (expand-file-name n prj-directory
))
656 (b (get-file-buffer f
))
661 (setq b
(find-file-noselect f
))
664 (with-current-buffer b
671 (eproject-setup-quit)
673 (prj-restore-edit-pos pos
(selected-window))
679 (defun prj-restore-edit-pos (pos w
)
681 (let* ((b (current-buffer))
685 (when (and (numberp top
) (numberp line
))
687 (set-window-start w
(point))
691 (defun prj-select-window (w)
692 (let (focus-follows-mouse)
694 (select-frame-set-input-focus (window-frame w
))
697 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
698 ;; choose next/previous file
700 (defun eproject-nextfile ()
701 "Switch to the next file that belongs to the current project."
703 (prj-switch-file 'prj-next-file
'next-buffer
)
706 (defun eproject-prevfile ()
707 "Switch to the previous file that belongs to the current project."
709 (prj-switch-file 'prj-prev-file
'previous-buffer
)
712 (defun prj-switch-file (fn1 fn2
)
713 (let* ((a (rassoc (current-buffer) prj-files
)))
715 (prj-edit-file (funcall fn1 prj-files a
))
718 (prj-edit-file prj-curfile
)
724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
727 (defun prj-setkeys ()
728 (let ((f (consp prj-current
))
729 (a (assoc 'eproject-mode minor-mode-map-alist
))
730 (map (make-sparse-keymap))
734 (push (cons 'eproject-mode map
) minor-mode-map-alist
)
737 (define-key map
[M-right
] 'eproject-nextfile
)
738 (define-key map
[M-left
] 'eproject-prevfile
)
739 (define-key map
[C-f5
] 'eproject-dired
)
741 (dolist (a prj-tools
)
742 (unless (setq fn
(nth n prj-tools-fns
))
743 (setq fn
(list 'lambda
))
744 (setq prj-tools-fns
(nconc prj-tools-fns
(list fn
)))
746 (setcdr fn
`(() (interactive) (prj-run-tool ',a
)))
748 (when (setq s
(caddr a
))
749 (define-key map
(prj-parse-key s
) (and f fn
))
751 (define-key map
[f5] 'eproject-setup-toggle)
754 (defun prj-parse-key (s)
756 (if (string-match "[a-z][a-z0-9]+$" s)
758 (concat "\"\\" s "\""))))
760 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
763 (defun prj-list-sorted ()
764 (sort (append prj-list nil)
765 '(lambda (a b) (string-lessp (car a) (car b)))
768 (defun prj-setmenu ()
769 (let ((f (consp prj-current)) m1 m2 m3)
774 ,@(prj-menulist-maker prj-list prj-current 'prj-menu-open)
776 ("Add ..." "Add new or existing project to the list" . eproject-add)
777 ("Remove ..." "Remove project from the list" . eproject-remove)
778 ,@(and f '(("Close" "Close current project" . eproject-close)))
780 '("Setup" "Enter the project setup area." . eproject-setup-toggle)
783 (nconc m1 (cons '("--") (prj-menulist-maker prj-tools nil prj-tools-fns)))
785 `(("Dired" "Browse project directory in Dired - Use 'a' to add file(s) to the project" . eproject-dired)
787 ,@(prj-menulist-maker prj-files prj-curfile 'prj-menu-edit)
792 `((buffer "Project" project ,@m1)
793 (file "List" list ,@m2)
798 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
800 (defun prj-menu-edit ()
802 (let ((a (nth last-command-event prj-files)))
803 (if a (prj-edit-file a))
806 (defun prj-menu-open ()
808 (let ((a (nth last-command-event prj-list)))
809 (if a (eproject-open (car a)))
812 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
814 (defun prj-menu-maker (map l v)
815 (let ((e (list nil)))
816 (setq v (append v e))
817 (dolist (k (reverse l))
819 (when (symbolp (car k))
826 ((and (consp (cdr k)) (symbolp (cadr k)))
829 (setq k (and s (cons (car k) (make-sparse-keymap (car k)))))
832 (setcar e (intern (downcase (car k))))
835 (define-key-after map (vconcat v) k a)
836 (define-key map (vconcat v) k)
838 (if s (prj-menu-maker map s v))
841 (defun prj-copy-head (l n)
843 (while (and l (> n 0))
850 (defun prj-split-list (l n)
853 (push (prj-copy-head l n) r)
854 (setq l (nthcdr n l))
859 (defun prj-menulist-maker (l act fns)
860 (let (r (w 30) s (m 0) (n 0) k)
863 (prj-menulist-maker-1 (list l fns n) act)
866 ;; menu too long; split into submenus
867 (setq s (prj-split-list l w))
868 (setq k (prj-menulist-maker-1 (list (append (pop s) '(("--"))) fns n) act))
869 (setq r (nreverse k))
872 (setq fns (nthcdr w fns))
875 (setq k (prj-menulist-maker-1 (list l fns n) act))
876 (push (cons (concat (prj-shortname (caar l)) " ...")
877 (cons (intern (format "m_%d" (setq m (1+ m))))
883 (defun prj-menulist-maker-1 (l act)
889 (setcar (cddr l) (1+ n))
890 (setq f (if (consp (cadr l))
891 (prog1 (car (cadr l)) (setcar (cdr l) (cdr (cadr l))))
895 (unless (string-match "^ *#" i)
896 (setq s (if (and (consp (cdr a)) (stringp (cadr a))) (cadr a) i))
898 (setq e (cons s (cons (intern s) (prj-menulist-maker-1 l act))))
905 (setq i (prj-shortname i))
906 (setq e (cons n (if (eq a act)
907 `(menu-item ,i ,f :button (:toggle . t) :help ,s)
908 (cons i (cons s f)))))
915 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
916 ;; Run make and other commands
918 (defun prj-setup-tool-window ()
919 (let ((bn "*compilation*") w h b c f)
920 (unless (get-buffer-window bn t)
921 (setq b (get-buffer-create bn))
922 (setq f (frame-list))
924 (setq w (frame-first-window (car f)))
925 (delete-other-windows w)
928 (setq h (/ (* 70 (frame-height)) 100))
929 (delete-other-windows w)
930 (setq w (split-window w h))
932 (set-window-buffer w b)
937 (when (string-match "^-in +\\([^[:space:]]+\\) +" cmd)
938 (setq dir (match-string-no-properties 1 cmd))
939 (setq cmd (substring cmd (match-end 0)))
941 (when prj-directory-run
942 (setq dir (expand-file-name (or dir ".") prj-directory-run))
945 (cond ((string-match "^-e +" cmd)
946 (setq cmd (read (substring cmd (match-end 0))))
947 (unless (commandp cmd)
948 (setq cmd `(lambda () (interactive) ,cmd))
950 (command-execute cmd)
952 ((string-match "\\(.+\\)& *$" cmd)
953 (start-process-shell-command "eproject-async" nil (match-string 1 cmd))
954 (message (match-string 1 cmd))
957 (unless (fboundp 'ecb-activate)
958 ;;(prj-setup-tool-window)
963 (defun prj-run-tool (a)
964 (unless (string-match "^--+$" (car a))
965 (prj-run (or (cadr a) (car a)))
968 (defun eproject-killtool ()
970 (let ((bn "*compilation*") w0 w1)
971 (when (setq w1 (get-buffer-window bn t))
972 (when (fboundp 'kill-compilation)
973 (setq w0 (selected-window))
979 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
980 ;; run grep on project files
984 (defun eproject-grep (command-args)
985 "Run the grep command on all the project files."
988 (grep-compute-defaults)
989 (let ((default (grep-default-command)))
990 (list (read-from-minibuffer
991 "Run grep on project files: "
992 (if current-prefix-arg default grep-command)
996 (if current-prefix-arg nil default)
998 (let ((default-directory prj-directory))
999 (dolist (f (mapcar 'car prj-files))
1000 (setq command-args (concat command-args " " f))
1005 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1006 ;; add files to the project with dired
1010 (defun prj-dired-addfiles ()
1014 (dolist (f (dired-get-marked-files))
1015 (setq a (prj-insert-file f))
1018 (setq prj-curfile a)
1020 (message "Added to project: %d file(s)" n)
1024 (defun prj-dired-run ()
1026 (let ((f (dired-get-marked-files)) c)
1027 (and (setq c (pop f))
1029 (let ((prj-directory (file-name-directory c)))
1032 (defun eproject-dired ()
1033 "Start a dired window with the project directory."
1035 (when prj-directory-run
1036 (eproject-setup-quit)
1037 ;;(message "Use 'a' to add marked or single files to the project.")
1038 (dired prj-directory-run)
1039 (let ((map dired-mode-map))
1040 (define-key map [mouse-2] 'dired-find-file)
1041 (define-key map "a" 'prj-dired-addfiles)
1042 (define-key map "r" 'prj-dired-run)
1043 (define-key map [menu-bar operate command] '("Add to Project"
1044 "Add current or marked file(s) to project" . prj-dired-addfiles))
1047 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1049 (defun prj-setup-all ()
1056 (defun prj-getconfig (n)
1057 (let ((a (cdr (assoc n prj-config))))
1061 (defun prj-setconfig (n v)
1062 (let ((a (assoc n prj-config)))
1065 (setq prj-config (nconc prj-config (list a)))
1070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1073 (defun prj-startup-delayed ()
1074 ;; where is this file
1075 (setq eproject-directory
1076 (file-name-directory (symbol-file 'eproject-startup)))
1079 (load (eproject-addon "eproject-config"))
1081 ;; When no projects are specified yet, load the eproject project itself.
1083 (load (eproject-addon "eproject.cfg"))
1086 ;; no project so far
1089 (add-hook 'kill-emacs-hook 'prj-saveall)
1091 ;; inhibit open last project when a file was on the commandline
1092 (unless (buffer-file-name (window-buffer))
1095 ;; open last project
1096 (eproject-open prj-last-open)
1098 ;; restore frame position
1099 '(when prj-frame-pos
1100 (modify-frame-parameters prj-initial-frame prj-frame-pos)
1101 ;; emacs bug: when it's too busy it doesn't set frames correctly.
1104 (when (fboundp 'ecb-activate)
1109 (defun prj-command-line-switch (option)
1110 (setq prj-last-open (pop argv))
1111 (setq inhibit-startup-screen t)
1114 (defun eproject-startup ()
1115 (if (boundp 'prj-list)
1117 (load (eproject-addon "eproject-config"))
1121 (when prj-last-open (setq inhibit-startup-screen t))
1122 (setq prj-initial-frame (selected-frame))
1123 (push '("project" . prj-command-line-switch) command-switch-alist)
1124 (run-with-idle-timer 0.1 nil 'prj-startup-delayed)
1127 ;;;###autoload(require 'eproject)
1131 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1132 ;; eproject.el ends here