diff options
| author | Szymon Szukalski <szymon@szymonszukalski.com> | 2026-04-09 09:30:06 +1000 |
|---|---|---|
| committer | Szymon Szukalski <szymon@szymonszukalski.com> | 2026-04-09 09:30:06 +1000 |
| commit | a9cb41ef7ae6fbd46dc6ff446c86b5df08f324b3 (patch) | |
| tree | b54f9306f95f272269d8dbea31d09d5e6af7921d /config.org | |
| parent | 018c70ae0ba8a8c3a7ece3a10fb0be2199e3af96 (diff) | |
Rename people commands to crm
Diffstat (limited to 'config.org')
| -rw-r--r-- | config.org | 393 |
1 files changed, 202 insertions, 191 deletions
@@ -287,73 +287,75 @@ The people workflow is a CRM backed by the canonical with properties for lookup, completion, reports, and abbrevs. Abbrev remains the fast path for names you type all the time, while CAPF plus Corfu remains the discovery path. The machine-facing layer only reads heading text and -properties; the =Context= and =TODOs= sections stay human-facing notes. +properties; the =Context= and =TODOs= sections stay human-facing notes. The +CRM stays individual-focused: =TEAM= captures the current working team and +=MANAGER= captures the formal organisational manager, but organisational +structure lives in separate notes rather than in the CRM itself. -The CRM is designed around =ss/people-overview=: opening the file starts in +The CRM is designed around =ss/crm-overview=: opening the file starts in overview mode, direct visits reset back to overview mode, and exiting card view means widening the buffer and restoring that overview. Keep =CURRENT_FOCUS= short and phrase-like so summaries and completion annotations stay readable. +Person cards use a flat property model in this order: =ROLE=, =TEAM=, +=MANAGER=, =ENGAGEMENT=, =LOCATION=, and =CURRENT_FOCUS=. =ABBREV= and +=ALIASES= remain optional helpers for lookup and insertion. #+begin_src emacs-lisp (require 'seq) (require 'subr-x) (require 'marginalia nil t) - (defconst ss/people-file + (defconst ss/crm-file (expand-file-name "areas/people/people.org" "~/org/") "Single source of truth for the people CRM.") - (defconst ss/people-engagement-values + (defconst ss/crm-engagement-values '("permanent" "contractor" "other") "Allowed engagement values for people cards.") - (defconst ss/people-relationship-values - '("direct-report" "stakeholder" "peer" "skip" "other") - "Allowed relationship values for people cards.") + (defvar ss/crm--cache nil + "Cached CRM entries loaded from `ss/crm-file'.") - (defvar ss/people--cache nil - "Cached CRM entries loaded from `ss/people-file'.") - - (defvar ss/people--cache-mtime nil + (defvar ss/crm--cache-mtime nil "Modification time of the cached CRM entries.") - (defun ss/people--entry-name (entry) + (defun ss/crm--entry-name (entry) "Return the canonical name in ENTRY." (plist-get entry :name)) - (defun ss/people--entry-abbrev (entry) + (defun ss/crm--entry-abbrev (entry) "Return the abbrev trigger in ENTRY." (plist-get entry :abbrev)) - (defun ss/people--entry-aliases (entry) + (defun ss/crm--entry-aliases (entry) "Return alias variants in ENTRY." (plist-get entry :aliases)) - (defun ss/people--entry-role (entry) + (defun ss/crm--entry-role (entry) "Return the role in ENTRY." (plist-get entry :role)) - (defun ss/people--entry-location (entry) + (defun ss/crm--entry-location (entry) "Return the location in ENTRY." (plist-get entry :location)) - (defun ss/people--entry-engagement (entry) + (defun ss/crm--entry-engagement (entry) "Return the engagement in ENTRY." (plist-get entry :engagement)) - (defun ss/people--entry-relationship (entry) - "Return the relationship in ENTRY." - (plist-get entry :relationship)) + (defun ss/crm--entry-manager (entry) + "Return the manager in ENTRY." + (plist-get entry :manager)) - (defun ss/people--entry-current-focus (entry) + (defun ss/crm--entry-current-focus (entry) "Return the current focus in ENTRY." (plist-get entry :current-focus)) - (defun ss/people--entry-team (entry) + (defun ss/crm--entry-team (entry) "Return the team in ENTRY." (plist-get entry :team)) - (defun ss/people-default-abbrev (name) + (defun ss/crm-default-abbrev (name) "Suggest a short abbrev trigger for NAME." (let* ((parts (split-string (string-trim name) "[[:space:]]+" t)) (first (downcase (substring (car parts) 0 (min 2 (length (car parts)))))) @@ -362,50 +364,50 @@ short and phrase-like so summaries and completion annotations stay readable. (concat ";" first last) (concat ";" first)))) - (defun ss/people--split-values (value) + (defun ss/crm--split-values (value) "Split VALUE on commas and trim each item." (when (and value (not (string-empty-p value))) (seq-filter (lambda (string) (not (string-empty-p string))) (mapcar #'string-trim (split-string value "," t))))) - (defun ss/people--summary (entry) + (defun ss/crm--summary (entry) "Return the compact one-line summary for ENTRY." (string-join (seq-filter (lambda (string) (and string (not (string-empty-p string)))) - (list (ss/people--entry-role entry) - (ss/people--entry-location entry) - (ss/people--entry-engagement entry) - (ss/people--entry-current-focus entry))) + (list (ss/crm--entry-role entry) + (ss/crm--entry-team entry) + (ss/crm--entry-engagement entry) + (ss/crm--entry-current-focus entry))) " | ")) - (defun ss/people--display (entry) + (defun ss/crm--display (entry) "Return the compact display string for ENTRY." - (let ((summary (ss/people--summary entry))) + (let ((summary (ss/crm--summary entry))) (if (string-empty-p summary) - (ss/people--entry-name entry) - (format "%s %s" (ss/people--entry-name entry) summary)))) + (ss/crm--entry-name entry) + (format "%s %s" (ss/crm--entry-name entry) summary)))) - (defun ss/people--property-line (key value) + (defun ss/crm--property-line (key value) "Return an Org property line for KEY and VALUE." (if (and value (not (string-empty-p value))) (format ":%s: %s\n" key value) "")) - (defun ss/people--require-file () - "Return `ss/people-file', signaling when it is unavailable." - (unless (file-exists-p ss/people-file) - (user-error "People file does not exist: %s" ss/people-file)) - ss/people-file) + (defun ss/crm--require-file () + "Return `ss/crm-file', signaling when it is unavailable." + (unless (file-exists-p ss/crm-file) + (user-error "People file does not exist: %s" ss/crm-file)) + ss/crm-file) - (defun ss/people-entries () - "Return top-level people cards from `ss/people-file'." - (let* ((file (ss/people--require-file)) + (defun ss/crm-entries () + "Return top-level people cards from `ss/crm-file'." + (let* ((file (ss/crm--require-file)) (attributes (file-attributes file)) (mtime (file-attribute-modification-time attributes))) - (unless (and ss/people--cache - (equal mtime ss/people--cache-mtime)) + (unless (and ss/crm--cache + (equal mtime ss/crm--cache-mtime)) (let ((entries (with-temp-buffer (insert-file-contents file) @@ -421,47 +423,48 @@ short and phrase-like so summaries and completion annotations stay readable. (goto-char (org-element-property :begin headline)) (push (list :name (org-element-property :raw-value headline) :abbrev (org-entry-get nil "ABBREV") - :aliases (ss/people--split-values + :aliases (ss/crm--split-values (org-entry-get nil "ALIASES")) :role (org-entry-get nil "ROLE") - :location (org-entry-get nil "LOCATION") + :team (org-entry-get nil "TEAM") + :manager (org-entry-get nil "MANAGER") :engagement (org-entry-get nil "ENGAGEMENT") - :relationship (org-entry-get nil "RELATIONSHIP") + :location (org-entry-get nil "LOCATION") :current-focus (org-entry-get nil "CURRENT_FOCUS") - :team (org-entry-get nil "TEAM")) + ) cards)))) (sort cards (lambda (left right) - (string< (ss/people--entry-name left) - (ss/people--entry-name right)))))))) - (setq ss/people--cache entries - ss/people--cache-mtime mtime))) - ss/people--cache)) + (string< (ss/crm--entry-name left) + (ss/crm--entry-name right)))))))) + (setq ss/crm--cache entries + ss/crm--cache-mtime mtime))) + ss/crm--cache)) - (defun ss/people-reload () + (defun ss/crm-reload () "Reload the people cache and refresh prose buffers." (interactive) - (setq ss/people--cache nil - ss/people--cache-mtime nil) - (ss/people-refresh-buffers) + (setq ss/crm--cache nil + ss/crm--cache-mtime nil) + (ss/crm-refresh-buffers) (message "Reloaded people CRM")) - (defun ss/people--entry-by-name (name) + (defun ss/crm--entry-by-name (name) "Return the people entry matching canonical NAME." (seq-find (lambda (entry) - (string= name (ss/people--entry-name entry))) - (ss/people-entries))) + (string= name (ss/crm--entry-name entry))) + (ss/crm-entries))) - (defun ss/people--search-keys (entry) + (defun ss/crm--search-keys (entry) "Return canonical and alias search keys for ENTRY." - (cons (ss/people--entry-name entry) - (ss/people--entry-aliases entry))) + (cons (ss/crm--entry-name entry) + (ss/crm--entry-aliases entry))) - (defun ss/people--match-p (query entry) + (defun ss/crm--match-p (query entry) "Return non-nil when QUERY matches ENTRY name or aliases." (let* ((parts (split-string (downcase (string-trim query)) "[[:space:]]+" t)) - (keys (mapcar #'downcase (ss/people--search-keys entry)))) + (keys (mapcar #'downcase (ss/crm--search-keys entry)))) (seq-every-p (lambda (part) (seq-some (lambda (key) @@ -469,105 +472,105 @@ short and phrase-like so summaries and completion annotations stay readable. keys)) parts))) - (defun ss/people--matching-entries (query) + (defun ss/crm--matching-entries (query) "Return entries whose canonical name or aliases match QUERY." - (let ((entries (ss/people-entries))) + (let ((entries (ss/crm-entries))) (if (string-empty-p (string-trim query)) entries (seq-filter (lambda (entry) - (ss/people--match-p query entry)) + (ss/crm--match-p query entry)) entries)))) - (defun ss/people--completion-table (string pred action) + (defun ss/crm--completion-table (string pred action) "Complete canonical people names while matching aliases via STRING." (if (eq action 'metadata) '(metadata (category . ss-person)) (complete-with-action action - (mapcar #'ss/people--entry-name (ss/people--matching-entries string)) + (mapcar #'ss/crm--entry-name (ss/crm--matching-entries string)) string pred))) - (defun ss/people-marginalia-annotator (candidate) + (defun ss/crm-marginalia-annotator (candidate) "Return a Marginalia annotation for person CANDIDATE." - (when-let ((entry (ss/people--entry-by-name candidate))) - (concat " " (ss/people--summary entry)))) + (when-let ((entry (ss/crm--entry-by-name candidate))) + (concat " " (ss/crm--summary entry)))) - (defun ss/people-select-entry (&optional prompt) + (defun ss/crm-select-entry (&optional prompt) "Select a person entry using PROMPT." - (let ((completion-extra-properties '(:annotation-function ss/people-marginalia-annotator))) - (ss/people--entry-by-name + (let ((completion-extra-properties '(:annotation-function ss/crm-marginalia-annotator))) + (ss/crm--entry-by-name (completing-read (or prompt "Person: ") - #'ss/people--completion-table + #'ss/crm--completion-table nil t)))) - (defun ss/people-overview () - "Open `ss/people-file' in overview mode, widening first when needed." + (defun ss/crm-overview () + "Open `ss/crm-file' in overview mode, widening first when needed." (interactive) (unless (and buffer-file-name (string= (file-truename buffer-file-name) - (file-truename ss/people-file))) - (find-file (ss/people--require-file))) + (file-truename ss/crm-file))) + (find-file (ss/crm--require-file))) (widen) (goto-char (point-min)) (org-overview) (org-cycle-hide-drawers 'all)) - (defun ss/people-open () - "Open the people CRM by delegating to `ss/people-overview'." + (defun ss/crm-open () + "Open the people CRM by delegating to `ss/crm-overview'." (interactive) - (ss/people-overview)) + (ss/crm-overview)) - (defun ss/people--track-buffer () - "Refresh CRM caches when `ss/people-file' is saved." + (defun ss/crm--track-buffer () + "Refresh CRM caches when `ss/crm-file' is saved." (when (and buffer-file-name (string= (file-truename buffer-file-name) - (file-truename ss/people-file))) - (add-hook 'after-save-hook #'ss/people-reload nil t))) + (file-truename ss/crm-file))) + (add-hook 'after-save-hook #'ss/crm-reload nil t))) - (defun ss/people--source-buffer-p () - "Return non-nil when the current buffer visits `ss/people-file'." + (defun ss/crm--source-buffer-p () + "Return non-nil when the current buffer visits `ss/crm-file'." (and buffer-file-name (string= (file-truename buffer-file-name) - (file-truename ss/people-file)))) + (file-truename ss/crm-file)))) - (defun ss/people--open-entry (entry) + (defun ss/crm--open-entry (entry) "Open the people CRM file, then narrow to ENTRY for card view." - (find-file (ss/people--require-file)) + (find-file (ss/crm--require-file)) (widen) (let ((position (org-find-exact-headline-in-buffer - (ss/people--entry-name entry)))) + (ss/crm--entry-name entry)))) (unless position - (user-error "No people card for %s" (ss/people--entry-name entry))) + (user-error "No people card for %s" (ss/crm--entry-name entry))) (goto-char position)) (org-narrow-to-subtree) (org-fold-show-subtree) (org-show-entry) (goto-char (point-min))) - (defun ss/people-find () + (defun ss/crm-find () "Find a person and open that card." (interactive) - (ss/people--open-entry - (or (ss/people-select-entry "Find person: ") + (ss/crm--open-entry + (or (ss/crm-select-entry "Find person: ") (user-error "No person selected")))) - (defun ss/people-insert-name () + (defun ss/crm-insert-name () "Insert a canonical person name at point." (interactive) - (let ((entry (or (ss/people-select-entry "Insert person name: ") + (let ((entry (or (ss/crm-select-entry "Insert person name: ") (user-error "No person selected")))) - (insert (ss/people--entry-name entry)))) + (insert (ss/crm--entry-name entry)))) - (defun ss/people-insert-summary () + (defun ss/crm-insert-summary () "Insert a compact person summary at point." (interactive) - (let ((entry (or (ss/people-select-entry "Insert person summary: ") + (let ((entry (or (ss/crm-select-entry "Insert person summary: ") (user-error "No person selected")))) - (insert (ss/people--display entry)))) + (insert (ss/crm--display entry)))) - (defun ss/people--report-buffer (title group-fn) + (defun ss/crm--report-buffer (title group-fn) "Render a grouped CRM report titled TITLE using GROUP-FN." (let ((groups (sort (seq-group-by @@ -576,7 +579,7 @@ short and phrase-like so summaries and completion annotations stay readable. (if (string-empty-p (or value "")) "(none)" value))) - (ss/people-entries)) + (ss/crm-entries)) (lambda (left right) (string< (car left) (car right)))))) (with-current-buffer (get-buffer-create "*People Report*") @@ -588,79 +591,86 @@ short and phrase-like so summaries and completion annotations stay readable. (insert "* " (car group) "\n") (dolist (entry (sort (copy-sequence (cdr group)) (lambda (left right) - (string< (ss/people--entry-name left) - (ss/people--entry-name right))))) - (insert "- " (ss/people--display entry) "\n"))) + (string< (ss/crm--entry-name left) + (ss/crm--entry-name right))))) + (insert "- " (ss/crm--display entry) "\n"))) (goto-char (point-min)) (read-only-mode 1) (view-mode 1)) (pop-to-buffer (current-buffer))))) - (defun ss/people-report-by-relationship () - "Show people grouped by relationship." + (defun ss/crm-report-by-team () + "Show people grouped by team." + (interactive) + (ss/crm--report-buffer + "People by team" + #'ss/crm--entry-team)) + + (defun ss/crm-report-by-manager () + "Show people grouped by manager." (interactive) - (ss/people--report-buffer - "People by relationship" - #'ss/people--entry-relationship)) + (ss/crm--report-buffer + "People by manager" + #'ss/crm--entry-manager)) - (defun ss/people-report-by-engagement () + (defun ss/crm-report-by-engagement () "Show people grouped by engagement." (interactive) - (ss/people--report-buffer + (ss/crm--report-buffer "People by engagement" - #'ss/people--entry-engagement)) + #'ss/crm--entry-engagement)) - (defun ss/people-report-by-role () + (defun ss/crm-report-by-role () "Show people grouped by role." (interactive) - (ss/people--report-buffer + (ss/crm--report-buffer "People by role" - #'ss/people--entry-role)) + #'ss/crm--entry-role)) - (defun ss/people-report-by-location () + (defun ss/crm-report-by-location () "Show people grouped by location." (interactive) - (ss/people--report-buffer + (ss/crm--report-buffer "People by location" - #'ss/people--entry-location)) + #'ss/crm--entry-location)) - (defun ss/people-read-string (prompt &optional default) + (defun ss/crm-read-string (prompt &optional default) "Read PROMPT and trim the result." (string-trim (read-string prompt nil nil default))) - (defun ss/people-read-required-string (prompt &optional default) + (defun ss/crm-read-required-string (prompt &optional default) "Read PROMPT and require a non-empty result." - (let ((value (ss/people-read-string prompt default))) + (let ((value (ss/crm-read-string prompt default))) (if (string-empty-p value) (user-error "%s is required" (string-remove-suffix ": " prompt)) value))) - (defun ss/people-read-optional-string (prompt) + (defun ss/crm-read-optional-string (prompt) "Read PROMPT and return nil when the answer is empty." - (let ((value (ss/people-read-string prompt))) + (let ((value (ss/crm-read-string prompt))) (unless (string-empty-p value) value))) - (defun ss/people-add () - "Add a new compact person card to `ss/people-file'." + (defun ss/crm-add () + "Add a new compact person card to `ss/crm-file'." (interactive) - (let* ((name (ss/people-read-required-string "Full name: ")) - (abbrev (ss/people-read-string "Abbrev: " (ss/people-default-abbrev name))) - (aliases (ss/people-read-string "Aliases (comma-separated, optional): ")) - (role (ss/people-read-required-string "Role: ")) - (location (ss/people-read-required-string "Location: ")) + (let* ((name (ss/crm-read-required-string "Full name: ")) + (abbrev (ss/crm-read-string "Abbrev: " (ss/crm-default-abbrev name))) + (aliases (ss/crm-read-string "Aliases (comma-separated, optional): ")) + (role (ss/crm-read-required-string "Role: ")) + (team (ss/crm-read-required-string "Team: ")) + (manager (ss/crm-read-required-string "Manager: ")) (engagement (completing-read "Engagement: " - ss/people-engagement-values nil t nil nil + ss/crm-engagement-values nil t nil nil "permanent")) - (relationship (completing-read "Relationship: " - ss/people-relationship-values nil t)) - (current-focus (ss/people-read-required-string "Current focus: ")) - (team (ss/people-read-optional-string "Team (optional): "))) - (when (ss/people--entry-by-name name) + (location (ss/crm-read-required-string "Location: ")) + (current-focus (ss/crm-read-required-string "Current focus: ")) + ) + (when (ss/crm--entry-by-name name) (user-error "A person card for %s already exists" name)) (when (string-empty-p abbrev) - (setq abbrev (ss/people-default-abbrev name))) - (find-file (ss/people--require-file)) + (setq abbrev (ss/crm-default-abbrev name))) + (find-file (ss/crm--require-file)) (widen) (goto-char (point-max)) (unless (bolp) @@ -669,54 +679,54 @@ short and phrase-like so summaries and completion annotations stay readable. (insert "\n")) (insert "* " name "\n" ":PROPERTIES:\n" - (ss/people--property-line "ABBREV" abbrev) - (ss/people--property-line "ALIASES" aliases) - (ss/people--property-line "ROLE" role) - (ss/people--property-line "LOCATION" location) - (ss/people--property-line "ENGAGEMENT" engagement) - (ss/people--property-line "RELATIONSHIP" relationship) - (ss/people--property-line "CURRENT_FOCUS" current-focus) - (ss/people--property-line "TEAM" team) + (ss/crm--property-line "ABBREV" abbrev) + (ss/crm--property-line "ALIASES" aliases) + (ss/crm--property-line "ROLE" role) + (ss/crm--property-line "TEAM" team) + (ss/crm--property-line "MANAGER" manager) + (ss/crm--property-line "ENGAGEMENT" engagement) + (ss/crm--property-line "LOCATION" location) + (ss/crm--property-line "CURRENT_FOCUS" current-focus) ":END:\n\n" "** Context\n\n" "** TODOs\n") (save-buffer) - (ss/people-reload) - (ss/people--open-entry (ss/people--entry-by-name name)))) + (ss/crm-reload) + (ss/crm--open-entry (ss/crm--entry-by-name name)))) - (defun ss/people--clear-installed-abbrevs () + (defun ss/crm--clear-installed-abbrevs () "Remove people-specific abbrevs from the current local table." (mapatoms (lambda (symbol) - (when (abbrev-get symbol :ss/people) + (when (abbrev-get symbol :ss/crm) (define-abbrev local-abbrev-table (symbol-name symbol) nil))) local-abbrev-table)) - (defun ss/people-install-abbrevs () + (defun ss/crm-install-abbrevs () "Install people abbrevs into the current buffer." - (unless (ss/people--source-buffer-p) + (unless (ss/crm--source-buffer-p) (setq-local local-abbrev-table (copy-abbrev-table local-abbrev-table)) - (ss/people--clear-installed-abbrevs) - (dolist (entry (ss/people-entries)) - (let* ((name (ss/people--entry-name entry)) - (abbrev (ss/people--entry-abbrev entry)) + (ss/crm--clear-installed-abbrevs) + (dolist (entry (ss/crm-entries)) + (let* ((name (ss/crm--entry-name entry)) + (abbrev (ss/crm--entry-abbrev entry)) (abbrev-name (if (or (null abbrev) (string-empty-p abbrev)) - (ss/people-default-abbrev name) + (ss/crm-default-abbrev name) abbrev))) (define-abbrev local-abbrev-table abbrev-name name) (when-let ((abbrev-symbol (abbrev-symbol abbrev-name local-abbrev-table))) - (abbrev-put abbrev-symbol :ss/people t)))))) + (abbrev-put abbrev-symbol :ss/crm t)))))) - (defun ss/people-refresh-buffers () + (defun ss/crm-refresh-buffers () "Refresh people abbrevs in every prose buffer." (dolist (buffer (buffer-list)) (with-current-buffer buffer (when (and (bound-and-true-p abbrev-mode) (derived-mode-p 'text-mode 'org-mode)) - (ss/people-install-abbrevs))))) + (ss/crm-install-abbrevs))))) - (defun ss/people-capf () + (defun ss/crm-capf () "Return canonical people completions at a word boundary." (let ((end (point))) (save-excursion @@ -726,28 +736,28 @@ short and phrase-like so summaries and completion annotations stay readable. ;; Verify this in real Org/text writing buffers, not just by inspection. (let ((annotation (lambda (candidate) - (when-let ((entry (ss/people--entry-by-name candidate))) - (concat " " (ss/people--summary entry))))) + (when-let ((entry (ss/crm--entry-by-name candidate))) + (concat " " (ss/crm--summary entry))))) (docsig (lambda (candidate) - (when-let ((entry (ss/people--entry-by-name candidate))) - (ss/people--summary entry))))) - (list beg end #'ss/people--completion-table + (when-let ((entry (ss/crm--entry-by-name candidate))) + (ss/crm--summary entry))))) + (list beg end #'ss/crm--completion-table :exclusive 'no :annotation-function annotation :company-docsig docsig))))))) (defun ss/enable-people-capf () - "Add `ss/people-capf' once in prose buffers." - (unless (or (ss/people--source-buffer-p) - (memq #'ss/people-capf completion-at-point-functions)) - (add-hook 'completion-at-point-functions #'ss/people-capf nil t))) + "Add `ss/crm-capf' once in prose buffers." + (unless (or (ss/crm--source-buffer-p) + (memq #'ss/crm-capf completion-at-point-functions)) + (add-hook 'completion-at-point-functions #'ss/crm-capf nil t))) - (defun ss/people--maybe-overview-buffer () + (defun ss/crm--maybe-overview-buffer () "Reset the people CRM buffer to overview when visiting it directly." (when (and buffer-file-name (string= (file-truename buffer-file-name) - (file-truename ss/people-file))) + (file-truename ss/crm-file))) (widen) (goto-char (point-min)) (org-overview) @@ -755,9 +765,9 @@ short and phrase-like so summaries and completion annotations stay readable. (dolist (hook '(text-mode-hook org-mode-hook)) (add-hook hook #'ss/enable-people-capf) - (add-hook hook #'ss/people-install-abbrevs)) - (add-hook 'find-file-hook #'ss/people--track-buffer) - (add-hook 'find-file-hook #'ss/people--maybe-overview-buffer) + (add-hook hook #'ss/crm-install-abbrevs)) + (add-hook 'find-file-hook #'ss/crm--track-buffer) + (add-hook 'find-file-hook #'ss/crm--maybe-overview-buffer) #+end_src * Notes workflow @@ -984,17 +994,18 @@ When CREATE is non-nil, create the datetree entry when missing." :bind (("C-c a" . ss/open-agenda) ("C-c c" . org-capture) ("C-c n M" . ss/open-moc) - ("C-c n E" . ss/people-report-by-engagement) - ("C-c n f" . ss/people-find) - ("C-c n i" . ss/people-insert-name) - ("C-c n I" . ss/people-insert-summary) - ("C-c n L" . ss/people-report-by-location) + ("C-c n E" . ss/crm-report-by-engagement) + ("C-c n f" . ss/crm-find) + ("C-c n i" . ss/crm-insert-name) + ("C-c n I" . ss/crm-insert-summary) + ("C-c n L" . ss/crm-report-by-location) ("C-c n d" . ss/open-journal) - ("C-c n o" . ss/people-overview) - ("C-c n O" . ss/people-report-by-role) - ("C-c n p" . ss/people-open) - ("C-c n P" . ss/people-add) - ("C-c n R" . ss/people-report-by-relationship)) + ("C-c n o" . ss/crm-overview) + ("C-c n O" . ss/crm-report-by-role) + ("C-c n p" . ss/crm-open) + ("C-c n P" . ss/crm-add) + ("C-c n R" . ss/crm-report-by-manager) + ("C-c n T" . ss/crm-report-by-team)) :config (setq org-directory ss/org-directory org-hide-emphasis-markers t @@ -1015,7 +1026,7 @@ own Org integration so note identity, metadata, and directories stay under Denote's control rather than custom code. The convenience templates keep the familiar entry points, but only project capture injects a structural keyword by default. The people CRM lives outside =org-capture=: adding a person uses the -dedicated =ss/people-add= command so =~/org/areas/people/people.org= stays a +dedicated =ss/crm-add= command so =~/org/areas/people/people.org= stays a compact, structured card file rather than turning into another capture target. #+begin_src emacs-lisp |
