diff --git a/nixos/flake.lock b/nixos/flake.lock index cc60f74c..e1d0c541 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -1756,11 +1756,11 @@ ] }, "locked": { - "lastModified": 1768413426, - "narHash": "sha256-JqIQYMO3a0J7UPS7edXie8fVrSMX+mMZKJjyGvNbZeE=", + "lastModified": 1768420684, + "narHash": "sha256-0f5aQ9vkIL8gHHUntCv6KWlZXatOlU2lzW8wuDi1rXg=", "owner": "colonelpanic8", "repo": "org-agenda-api", - "rev": "f342ee0b73ccd48a7aff12ca07bd742a96c1776e", + "rev": "8b499275f31436f36ca4d775f611208edab72d51", "type": "github" }, "original": { diff --git a/nixos/flake.nix b/nixos/flake.nix index d464aba1..66079281 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -331,101 +331,9 @@ inputs.flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; - - # Path to org-config.org in the dotfiles - orgConfigOrg = ../dotfiles/emacs.d/org-config.org; - - # Tangle org-config.org and create a loader for the container - orgAgendaCustomConfig = pkgs.runCommand "org-agenda-custom-config" { - buildInputs = [ pkgs.emacs-nox ]; - } '' - mkdir -p $out - mkdir -p work - - # Copy org file to writable location (tangle writes to same directory) - cp ${orgConfigOrg} work/org-config.org - - # Tangle org-config.org - emacs --batch \ - --eval '(require (quote org))' \ - --eval '(org-babel-tangle-file "work/org-config.org")' - - # Copy all tangled files to output - for f in work/org-config-*.el; do - if [ -f "$f" ]; then - cp "$f" $out/ - fi - done - - # Create a loader that sets up paths and loads files in order - cat > $out/custom-config.el << 'ELISP' -;;; custom-config.el --- Container config loader -*- lexical-binding: t; -*- - -;; Set org directory for container -(defvar imalison:org-dir "/data/org") -(defvar imalison:shared-org-dir nil) - -;; Helper function used by org-config -(defun imalison:join-paths (&rest paths) - "Join PATHS together into a single path." - (let ((result (car paths))) - (dolist (p (cdr paths)) - (setq result (expand-file-name p result))) - result)) - -;; Load tangled config files in order -(let ((config-dir (file-name-directory load-file-name))) - (when (file-exists-p (expand-file-name "org-config-preface.el" config-dir)) - (load (expand-file-name "org-config-preface.el" config-dir))) - ;; org-config-custom.el uses customize format (var value), convert to setq - (when (file-exists-p (expand-file-name "org-config-custom.el" config-dir)) - (with-temp-buffer - (insert-file-contents (expand-file-name "org-config-custom.el" config-dir)) - (goto-char (point-min)) - (condition-case nil - (while t - (let ((form (read (current-buffer)))) - (when (and (listp form) (symbolp (car form))) - (set (car form) (eval (cadr form)))))) - (end-of-file nil)))) - (when (file-exists-p (expand-file-name "org-config-config.el" config-dir)) - (load (expand-file-name "org-config-config.el" config-dir)))) - -;; Capture templates for API -(setq org-agenda-api-capture-templates - `(("gtd-todo" - :name "GTD Todo" - :template ("t" "Todo" entry (file ,(imalison:join-paths imalison:org-dir "inbox.org")) - "* INBOX %^{Title}\n:PROPERTIES:\n:CREATED: %U\n:END:\n" - :immediate-finish t) - :prompts (("Title" :type string :required t))) - ("scheduled-todo" - :name "Scheduled Todo" - :template ("s" "Scheduled" entry (file ,(imalison:join-paths imalison:org-dir "inbox.org")) - "* INBOX %^{Title}\nSCHEDULED: %^{When}t\n:PROPERTIES:\n:CREATED: %U\n:END:\n" - :immediate-finish t) - :prompts (("Title" :type string :required t) - ("When" :type date :required t))) - ("deadline-todo" - :name "Todo with Deadline" - :template ("d" "Deadline" entry (file ,(imalison:join-paths imalison:org-dir "inbox.org")) - "* INBOX %^{Title}\nDEADLINE: %^{When}t\n:PROPERTIES:\n:CREATED: %U\n:END:\n" - :immediate-finish t) - :prompts (("Title" :type string :required t) - ("When" :type date :required t))))) -ELISP - ''; - - # Build customized org-agenda-api container - orgAgendaApiContainer = inputs.org-agenda-api.lib.${system}.mkContainer { - customElispFile = "${orgAgendaCustomConfig}/custom-config.el"; - }; - + orgAgendaPackages = import ./org-agenda-api.nix { inherit pkgs inputs system; }; in { - packages = { - org-agenda-custom-config = orgAgendaCustomConfig; - org-agenda-api-container = orgAgendaApiContainer; - }; + packages = orgAgendaPackages; } ); } diff --git a/nixos/org-agenda-api.nix b/nixos/org-agenda-api.nix new file mode 100644 index 00000000..9b98ec6a --- /dev/null +++ b/nixos/org-agenda-api.nix @@ -0,0 +1,96 @@ +# org-agenda-api.nix - Container and config for org-agenda-api +{ pkgs, inputs, system }: +let + # Path to org-config.org in the dotfiles + orgConfigOrg = ../dotfiles/emacs.d/org-config.org; + + # Tangle org-config.org and create a loader for the container + orgAgendaCustomConfig = pkgs.runCommand "org-agenda-custom-config" { + buildInputs = [ pkgs.emacs-nox ]; + } '' + mkdir -p $out + mkdir -p work + + # Copy org file to writable location (tangle writes to same directory) + cp ${orgConfigOrg} work/org-config.org + + # Tangle org-config.org + emacs --batch \ + --eval '(require (quote org))' \ + --eval '(org-babel-tangle-file "work/org-config.org")' + + # Copy all tangled files to output + for f in work/org-config-*.el; do + if [ -f "$f" ]; then + cp "$f" $out/ + fi + done + + # Create a loader that sets up paths and loads files in order + cat > $out/custom-config.el << 'ELISP' +;;; custom-config.el --- Container config loader -*- lexical-binding: t; -*- + +;; Set org directory for container +(defvar imalison:org-dir "/data/org") +(defvar imalison:shared-org-dir nil) + +;; Helper function used by org-config +(defun imalison:join-paths (&rest paths) + "Join PATHS together into a single path." + (let ((result (car paths))) + (dolist (p (cdr paths)) + (setq result (expand-file-name p result))) + result)) + +;; Load tangled config files in order +(let ((config-dir (file-name-directory load-file-name))) + (when (file-exists-p (expand-file-name "org-config-preface.el" config-dir)) + (load (expand-file-name "org-config-preface.el" config-dir))) + ;; org-config-custom.el uses customize format (var value), convert to setq + (when (file-exists-p (expand-file-name "org-config-custom.el" config-dir)) + (with-temp-buffer + (insert-file-contents (expand-file-name "org-config-custom.el" config-dir)) + (goto-char (point-min)) + (condition-case nil + (while t + (let ((form (read (current-buffer)))) + (when (and (listp form) (symbolp (car form))) + (set (car form) (eval (cadr form)))))) + (end-of-file nil)))) + (when (file-exists-p (expand-file-name "org-config-config.el" config-dir)) + (load (expand-file-name "org-config-config.el" config-dir)))) + +;; Capture templates for API +(setq org-agenda-api-capture-templates + `(("gtd-todo" + :name "GTD Todo" + :template ("g" "GTD Todo" entry (file ,imalison:org-gtd-file) + (function (lambda () (imalison:make-org-todo-template :content "%^{Title}"))) + :immediate-finish t) + :prompts (("Title" :type string :required t))) + ("scheduled-todo" + :name "Scheduled Todo" + :template ("s" "Scheduled" entry (file ,(imalison:join-paths imalison:org-dir "inbox.org")) + "* INBOX %^{Title}\nSCHEDULED: %^{When}t\n:PROPERTIES:\n:CREATED: %U\n:END:\n" + :immediate-finish t) + :prompts (("Title" :type string :required t) + ("When" :type date :required t))) + ("deadline-todo" + :name "Todo with Deadline" + :template ("d" "Deadline" entry (file ,(imalison:join-paths imalison:org-dir "inbox.org")) + "* INBOX %^{Title}\nDEADLINE: %^{When}t\n:PROPERTIES:\n:CREATED: %U\n:END:\n" + :immediate-finish t) + :prompts (("Title" :type string :required t) + ("When" :type date :required t))))) +ELISP + ''; + + # Build customized org-agenda-api container + orgAgendaApiContainer = inputs.org-agenda-api.lib.${system}.mkContainer { + customElispFile = "${orgAgendaCustomConfig}/custom-config.el"; + }; + +in { + org-agenda-custom-config = orgAgendaCustomConfig; + org-agenda-api-container = orgAgendaApiContainer; +}