Compare commits
5 Commits
4997f21bec
...
4b4f187869
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b4f187869 | |||
| 425792a2ee | |||
| 72d6904968 | |||
| 7663b82800 | |||
| 137bafeb0b |
@ -1,14 +1,11 @@
|
|||||||
;;; db-projects.el -- Simple Directory-Based Project Management -*- lexical-binding: t -*-
|
;;; db-projects.el -- Simple Directory-Based Project Management -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; TODO: this package is deprecated and should be replaced or at least built
|
|
||||||
;; upon either project.el or projectile.
|
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; A project is simply a directory under `projects-main-project-directory'
|
;; A project is simply a directory under `projects-main-project-directory'
|
||||||
;; containing either .git or .projectile. This little collection of functions
|
;; containing either .git or .projectile. This little collection of functions
|
||||||
;; helps to manage these project directories and also integration them
|
;; helps to manage these project directories and integrate them consistently
|
||||||
;; consistently with the projectile package.
|
;; with the projectile package.
|
||||||
|
|
||||||
;; To start, first customize `projects-main-project-directory' and
|
;; To start, first customize `projects-main-project-directory' and
|
||||||
;; `projects-archive-directory' as needed. Then use `projects-add-project' to
|
;; `projects-archive-directory' as needed. Then use `projects-add-project' to
|
||||||
@ -24,8 +21,10 @@
|
|||||||
(require 'bookmark)
|
(require 'bookmark)
|
||||||
(require 'projectile)
|
(require 'projectile)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defgroup projects nil
|
(defgroup projects nil
|
||||||
"Simple directory-based project management"
|
"Simple directory-based project management."
|
||||||
:tag "Project Management"
|
:tag "Project Management"
|
||||||
:group 'projects)
|
:group 'projects)
|
||||||
|
|
||||||
@ -39,6 +38,8 @@
|
|||||||
:group 'projects
|
:group 'projects
|
||||||
:type 'directory)
|
:type 'directory)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defun projects-project-exists-p (short-name)
|
(defun projects-project-exists-p (short-name)
|
||||||
"Check whether a project named SHORT-NAME already exists."
|
"Check whether a project named SHORT-NAME already exists."
|
||||||
(or
|
(or
|
||||||
@ -56,14 +57,12 @@
|
|||||||
nil "^[^.]")))
|
nil "^[^.]")))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun projects-add-project (short-name long-name)
|
(defun projects-add-project (short-name)
|
||||||
"Add new project with SHORT-NAME and LONG-NAME.
|
"Add new project with SHORT-NAME.
|
||||||
The project directory will be located under
|
The project directory will be located under
|
||||||
`projects-main-project-directory' within a directory named
|
`projects-main-project-directory' within a directory named
|
||||||
SHORT-NAME. A bookmark to the project diary will be created,
|
SHORT-NAME."
|
||||||
using the given LONG-NAME. The project diary will be pre-filled
|
(interactive "sShort Name: ")
|
||||||
with some standard information like title and creation date."
|
|
||||||
(interactive "sShort Name: \nsLong Name: ")
|
|
||||||
(when (projects-project-exists-p short-name)
|
(when (projects-project-exists-p short-name)
|
||||||
(user-error "Project %s already exists, exiting" short-name))
|
(user-error "Project %s already exists, exiting" short-name))
|
||||||
(when (file-exists-p (expand-file-name short-name
|
(when (file-exists-p (expand-file-name short-name
|
||||||
@ -73,30 +72,11 @@ with some standard information like title and creation date."
|
|||||||
projects-main-project-directory))
|
projects-main-project-directory))
|
||||||
(default-directory project-directory))
|
(default-directory project-directory))
|
||||||
(make-directory project-directory)
|
(make-directory project-directory)
|
||||||
(make-directory (expand-file-name "scripts"))
|
|
||||||
(make-directory (expand-file-name "data"))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert (format "#+title: %s\n" long-name))
|
|
||||||
(insert (format "#+created: %s\n\n"
|
|
||||||
(format-time-string "[%Y-%m-%d %a %H:%M]" (current-time))))
|
|
||||||
(write-file (expand-file-name "projekttagebuch.org"))
|
|
||||||
(bookmark-set (format "Projekttagebuch %s" long-name)))
|
|
||||||
(if-let ((git-executable (executable-find "git")))
|
(if-let ((git-executable (executable-find "git")))
|
||||||
(call-process git-executable nil nil nil "init")
|
(call-process git-executable nil nil nil "init")
|
||||||
(write-region "" nil (expand-file-name ".projectile")))
|
(write-region "" nil (expand-file-name ".projectile")))
|
||||||
(projectile-add-known-project project-directory)))
|
(projectile-add-known-project project-directory)))
|
||||||
|
|
||||||
(defun projects--find-bookmarks-for-path (path)
|
|
||||||
"Find all bookmark names that point into PATH."
|
|
||||||
(unless (file-name-absolute-p path)
|
|
||||||
(user-error "Given path %s is not absolute" path))
|
|
||||||
(let ((path (file-truename path)))
|
|
||||||
(cl-remove-if-not #'(lambda (bmk)
|
|
||||||
(let ((filename (bookmark-get-filename bmk)))
|
|
||||||
(and (not (file-remote-p filename))
|
|
||||||
(string-prefix-p path (file-truename filename)))))
|
|
||||||
(bookmark-all-names))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun projects-archive-project (short-name)
|
(defun projects-archive-project (short-name)
|
||||||
"Archive existing project identified by SHORT-NAME.
|
"Archive existing project identified by SHORT-NAME.
|
||||||
@ -115,9 +95,6 @@ project, and updating projectile's cache."
|
|||||||
(when (file-exists-p archive-path)
|
(when (file-exists-p archive-path)
|
||||||
(user-error "Archived project named %s already exists, aborting" short-name))
|
(user-error "Archived project named %s already exists, aborting" short-name))
|
||||||
|
|
||||||
;; Remove bookmarks first
|
|
||||||
(mapc #'bookmark-delete (projects--find-bookmarks-for-path project-path))
|
|
||||||
|
|
||||||
;; Move project directory into archive
|
;; Move project directory into archive
|
||||||
(unless (file-exists-p projects-archive-directory)
|
(unless (file-exists-p projects-archive-directory)
|
||||||
(make-directory projects-archive-directory))
|
(make-directory projects-archive-directory))
|
||||||
@ -153,31 +130,6 @@ in `org-agenda-files'."
|
|||||||
(gethash (file-truename org-file) extra-files nil))
|
(gethash (file-truename org-file) extra-files nil))
|
||||||
(projects--org-files))))
|
(projects--org-files))))
|
||||||
|
|
||||||
(defun projects-check-project-diary-bookmarks ()
|
|
||||||
"Check that all known projects have a bookmark to their diary.
|
|
||||||
Return list of short names of projects whose project diaries do
|
|
||||||
not have a corresponding bookmark."
|
|
||||||
;; Make hash table of all diary paths to all known projects; as values we
|
|
||||||
;; keep the short names, because these are the ones we want to return in the
|
|
||||||
;; end
|
|
||||||
(let ((projects (make-hash-table :test #'equal)))
|
|
||||||
|
|
||||||
(dolist (project (projects-existing-projects))
|
|
||||||
(let ((project-diary-path (expand-file-name (concat (file-name-as-directory project)
|
|
||||||
"projekttagebuch.org")
|
|
||||||
projects-main-project-directory)))
|
|
||||||
(when (file-exists-p project-diary-path)
|
|
||||||
(puthash (file-truename project-diary-path) project projects))))
|
|
||||||
|
|
||||||
;; Delete all those diary links that have a bookmark
|
|
||||||
(dolist (bmkn (bookmark-all-names))
|
|
||||||
(unless (file-remote-p (bookmark-get-filename bmkn))
|
|
||||||
(remhash (file-truename (bookmark-get-filename bmkn)) projects)))
|
|
||||||
|
|
||||||
;; Return remaining short names; those are the ones that do not have a
|
|
||||||
;; bookmark yet
|
|
||||||
(hash-table-values projects)))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun projects-lint-projects ()
|
(defun projects-lint-projects ()
|
||||||
"Check all known projects for proper configuration.
|
"Check all known projects for proper configuration.
|
||||||
@ -195,9 +147,6 @@ through all included Org Mode files."
|
|||||||
(insert "\n " file))
|
(insert "\n " file))
|
||||||
(insert "\n\n"))
|
(insert "\n\n"))
|
||||||
|
|
||||||
(when-let ((missing-bookmarks (projects-check-project-diary-bookmarks)))
|
|
||||||
(insert "The following projects do not have a project diary bookmark: " (apply #'concat missing-bookmarks)))
|
|
||||||
|
|
||||||
(display-buffer (current-buffer))))
|
(display-buffer (current-buffer))))
|
||||||
|
|
||||||
(provide 'db-projects)
|
(provide 'db-projects)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user