(defvar *red-core* "~/red/core/") (defvar *red-core-data* "~/red/data/") (defun create-core-from-region () (interactive) (kill-ring-save (mark) (point)) (find-file-other-window (concat *red-core* (string-trim-right (shell-command-to-string "uuidgen")) ".org")) (insert "#+TAGS: ") (newline) (newline) (yank) (beginning-of-buffer) (end-of-line)) (defun create-core-from-file-at-point-copy () (interactive) (create-core-from-file :copy :dired)) (defun create-core-from-file-at-point-move () (interactive) (create-core-from-file :move :dired)) (defun create-core-from-current-file-copy () (interactive) (create-core-from-file :copy :current)) (defun create-core-from-current-file-move () (interactive) (create-core-from-file :move :current)) (defun create-core-from-file (creation-method file-source) (cl-assert (or (equal creation-method :copy) (equal creation-method :move)) "The :creation-method should be one of :copy or :move") (cl-assert (or (equal file-source :current) (equal file-source :dired)) "The :file-source should be one of :current or :dired") (let* ((original-file-path (cl-case file-source (:current (buffer-file-name)) (:dired (dired-get-filename)))) (file-name (file-name-nondirectory original-file-path)) (uuid (string-trim-right (shell-command-to-string "uuidgen"))) (file-namespace-dir (concat *red-core-data* (car (split-string uuid "-")) "/")) (file-dir (concat file-namespace-dir uuid "/"))) (mapcar (lambda (dir) (unless (file-directory-p dir) (dired-create-directory dir))) (list *red-core-data* file-namespace-dir file-dir)) (cl-case creation-method (:move (dired-rename-file original-file-path (concat file-dir file-name) nil)) (:copy (dired-copy-file original-file-path file-dir nil))) (find-file-other-window (concat *red-core* uuid ".org")) (insert "#+TAGS: :file:") (newline) (insert (concat "#+CREATE_DATE: ")) (org-insert-time-stamp (current-time) t 'inactive) (newline) (insert (concat "#+FILE: " "[[" file-dir file-name "]" "[" file-dir file-name "]]")) (newline) (beginning-of-buffer) (end-of-line) (save-buffer))) (defun list-garbage-collectable-core-files () (interactive) (let* ((namespace-dirs (directory-files *red-core-data* nil "[^\.]")) (binfile-uuids (cl-loop for namespace-dir in namespace-dirs collecting (directory-files (concat *red-core-data* namespace-dir) nil "[^\.]") into file-uuids finally (return (apply 'cl-concatenate (append '(list) file-uuids))))) (index-files (directory-files *red-core* nil "[^\.]")) (index-file-uuids (mapcar 'file-name-base index-files)) (garbage-collectable-files (cl-remove-if (lambda (file-uuid) (cl-find file-uuid index-file-uuids :test 'string-equal)) binfile-uuids))) (print garbage-collectable-files) garbage-collectable-files)) (defun garbage-collect-core-files () (interactive) (let* ((garbage-collectable-files (list-garbage-collectable-core-files))) (cl-loop for file in garbage-collectable-files as file-namespace-dir = (concat *red-core-data* (car (split-string file "-")) "/") as file-dir = (concat file-namespace-dir file) do (dired-delete-file file-dir 'always) (when (= 0 (length (directory-files file-namespace-dir nil "[^\.]"))) (dired-delete-file file-namespace-dir 'always))))) (defun create-core-new () (interactive) (find-file-other-window (concat *red-core* (string-trim-right (shell-command-to-string "uuidgen")) ".org")) (insert "#+TAGS: ") (newline) (newline)) (defun find-random-core () (interactive) (find-file (concat *red-core* (nth (random (length (directory-files *red-core*))) (cddr (directory-files *red-core*)))))) (defun find-review-core () (interactive) (cl-loop for file in (directory-files *red-core*) while (not (progn (find-file file) (goto-line 0) (cl-search ":to-review:" (buffer-substring-no-properties (line-beginning-position) (line-end-position))))) do (kill-this-buffer))) (defun delete-current-file () (interactive) (let ((filename (buffer-file-name))) (when filename (if (yes-or-no-p (format "Are you sure you want to delete %s " filename)) (if (vc-backend filename) (vc-delete-file filename) (progn (delete-file filename) (message "Deleted file %s" filename) (kill-buffer))))))) (defun search-red-core () (interactive) (counsel-ag (if (region-active-p) (filter-buffer-substring (mark) (point)) "") "~/red/core/" "-i --multiline")) (global-set-key (kbd "C-c c f") 'search-red-core) (global-set-key (kbd "C-c c c") 'create-core-from-region) (global-set-key (kbd "C-c c e") 'create-core-new) (global-set-key (kbd "C-c c r") 'find-random-core) (global-set-key (kbd "C-c c R") 'find-review-core) (global-set-key (kbd "C-c c D") 'delete-current-file) (global-set-key (kbd "C-c c y") 'create-core-from-file-at-point-copy) (global-set-key (kbd "C-c c Y") 'create-core-from-current-file-copy) (global-set-key (kbd "C-c c m") 'create-core-from-file-at-point-move) (global-set-key (kbd "C-c c M") 'create-core-from-current-file-move)