summaryrefslogtreecommitdiff
path: root/README.md
blob: 5579d601affd1fb0e5b982ff06a89fb9343fd6ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# Emacs Configuration

This repository contains a literate Emacs configuration built around Org mode, Denote, a PARA-style note layout, and a small completion stack. The hand-edited source is `config.org`; `init.el` and `early-init.el` are generated from it.

## Emacs Setup

### Source of truth and generated files

`config.org` is the only file intended for manual configuration edits. The generated startup files are:

- `early-init.el` for settings that must exist before the first GUI frame.
- `init.el` for the main runtime configuration.

Both generated files are tangled from `config.org` and should be treated as build artifacts.

### Package bootstrap

The config bootstraps packages with built-in `package.el` and uses `use-package` for declaration and load order. Package archives are configured with GNU, NonGNU ELPA, and MELPA, with GNU given highest priority.

### Core packages and built-in modules

The current setup uses these packages and built-in modules:

- `org` and `org-capture` for agenda, capture, daily notes, and the literate configuration itself.
- `denote` for durable notes, naming, keywords, and linking.
- `git-auto-commit-mode` for automatic note commits on save inside the notes repo.
- `vertico` for minibuffer completion UI.
- `orderless` for flexible completion matching.
- `marginalia` for minibuffer annotations.
- `gptel` with the GitHub Copilot backend for chat and rewrite workflows inside Emacs.
- `dired` with a macOS-safe `ls` configuration.
- `time` for the modeline clock.
- `modus-themes`, using `modus-vivendi` in the current config.

### Org mode and note layout

The note system lives under `~/org/` and is organized like this:

- `daily/` for plain daily Org files.
- `projects/` for project notes.
- `areas/` for area notes.
- `areas/people/` for people-related notes.
- `resources/` for reference material.
- `archives/` for archived notes.

This is a PARA-style layout, but the agenda is intentionally narrower than the full tree. Agenda files are discovered dynamically from `projects/` and `areas/` only. Daily notes, archives, and resources are excluded from the agenda scan.

Folder placement carries most of the structural meaning in this setup. Denote keywords are used sparingly, with `project` kept as the only built-in structural keyword because project titles are often ambiguous outside their folder.

### Completion setup

The minibuffer stack is intentionally small:

- `vertico` provides the completion UI.
- `orderless` handles matching.
- `marginalia` adds annotations.
- `corfu` handles in-buffer completion popups for text and Org buffers.

Name entry uses fixed abbrevs plus the roster:

- `abbrev` provides deterministic one-shot shortcuts for fixed name expansions.
- a CAPF feeds Corfu name variants from the legacy shortcut list and from the
  structured people roster in `~/org/areas/people/roster.org`.
- `M-x ss/name-dictionary-add-name` and `M-x ss/name-dictionary-remove-name` update the legacy shortcut file and refresh the current prose buffers.
- `M-x ss/name-dictionary-add-name-from-region` uses the active region as the name being added.
- `M-x ss/people-find` opens a roster entry.
- `M-x ss/people-insert-summary` inserts a compact roster summary at point.

### Persistent abbrevs

Persistent abbrevs live in `abbrev_defs` at the repository root. The config loads that file on startup, enables abbrev mode only in text-like buffers, and saves learned abbrevs back to the same file silently when buffers are saved.
The legacy name shortcut list lives in `name-dictionary.el`, and the structured roster in `~/org/areas/people/roster.org` is the source of truth for people records, including name, role, employee time, engagement, team, abbrev, aliases, manager, email, and location.

### Babel tangle process

The literate config uses Org Babel to generate the runtime files. Most Emacs Lisp blocks inherit `:tangle init.el` from the file header, while early-startup blocks explicitly tangle to `early-init.el`.

To regenerate the generated files from the repo root:

```sh
emacs --batch -Q --eval '(progn (require (quote ob-tangle)) (org-babel-tangle-file "config.org"))'
```

To verify that the generated main config still loads:

```sh
emacs --batch -Q --load ./init.el
```

## Workflow

### MOC

There is a central `~/org/moc.org` note. It is a deliberately small, curated navigation surface for the notes system rather than an exhaustive index or system of record, and the config assumes the file already exists.

The MOC opens automatically on Emacs startup through startup-hook behavior, but the config now just opens the file directly rather than creating it. `C-c n M` opens it manually at any time.

Its Quick Access section provides actionable links for opening the agenda, today's note, capture, and a new note, while the rest of the file stays lightweight and curated around active projects, areas, and a few high-leverage resources.

### Daily notes

Daily notes are plain Org files in `~/org/daily/`, named by date. When a daily note is created through the config, it starts with these headings:

- `Tasks`
- `Notes`
- `Open Loops`

Daily capture stays fast without routing everything through Denote.

### Agenda usage

The agenda is opened through `ss/open-agenda`, bound to `C-c a`. That command explicitly loads `org-agenda`, and the config refreshes `org-agenda-files` immediately before each `org-agenda` invocation so the agenda sees the current PARA files without relying on a fixed file list.

This means the agenda reflects the current project and area files at runtime instead of relying on a fixed file list. Daily notes, archives, and resources are outside the agenda scan.

### Capture flow

`C-c c` opens capture. The configured templates cover:

- daily tasks
- daily notes
- daily meetings
- Denote-backed captures for generic notes, projects, areas, people, and resources
- structured roster captures for manager-facing people data

Daily task capture writes under `Tasks`. Daily note capture and daily meeting capture both write under `Notes`, and the meeting template prefixes the heading with a timestamp and the word `meeting`.

Denote captures still prompt for title, keywords, and subdirectory placement where appropriate, but folder placement does most of the classification work. The project capture template prepopulates the `project` keyword. Area, person, and resource captures do not inject structural keywords automatically, and there is no Denote-backed meeting capture template.
The people roster capture template writes to `~/org/areas/people/roster.org` and records name, abbrev trigger, aliases, role, engagement, team, manager, email, and location. `C-c n f` opens the roster lookup prompt, and `C-c n r` opens the roster file directly. `M-x ss/people-report-by-engagement`, `M-x ss/people-report-by-role`, and `M-x ss/people-report-by-manager` generate filtered roster views.

### Note creation and linking

Denote handles long-lived notes. The main bindings are:

- `C-c n n` to open or create a Denote note.
- `C-c n l` to insert a Denote link.
- `C-c n M` to open the central MOC note.
- `C-c n f` to search the people roster.
- `C-c n m` to create a PARA subdirectory from the minibuffer before capturing into it.
- `C-c n d` to open today's daily note.
- `C-c n r` to open the roster file.

Keyword prompts and directory placement are part of the workflow, not an afterthought. The config is set up so structure is created first, then capture writes into it, with folder placement carrying most of the durable type information.

### Automatic note commits

The notes tree can opt into `git-auto-commit-mode` through a directory-local file at `~/org/.dir-locals.el`. In the current setup, the Emacs config installs the package and configures shell command chaining based on the active shell, while the notes repository carries its own auto-commit policy in directory locals.

When enabled for the notes tree, saving a file in `~/org/` makes Emacs try to commit that change to the notes repository. In the current `~/org/.dir-locals.el`, new files are added automatically, commits are debounced by 60 seconds, automatic pushing is enabled, and the default commit message is a timestamp in the form `Auto-commit: YYYY-MM-DD HH:MM:SS`.

Place this file at the root of the notes repository:

```emacs-lisp
((nil .
    ((eval .
        (progn
            (setq-local gac-automatically-add-new-files-p t
                        gac-automatically-push-p t
                        gac-debounce-interval 60
                        gac-default-message
                        (lambda (_filename)
                            (format-time-string "Auto-commit: %Y-%m-%d %H:%M:%S")))
            (git-auto-commit-mode 1))))))
```

That applies to buffers visiting files under `~/org/` and its subdirectories. The repository-local settings control whether new files are added, whether pushes occur, how long commits are debounced, and what commit message is used, while the Emacs config supplies the package itself and picks the correct shell command separator for the active shell.

### Terminal and GUI behavior

GUI Emacs and terminal Emacs are handled slightly differently.

- GUI frames get the preferred frame size, font setup, and UI trimming.
- In `emacs -nw`, the menu bar is disabled on `emacs-startup-hook` rather than earlier in startup, because changing that timing too early caused interactive terminal regressions in kitty.

If you change terminal behavior, test it in a real `emacs -nw` session. Batch load checks are necessary, but they are not enough for tty input and UI behavior.

## Maintenance Rules

- Update `config.org` first, then regenerate `init.el` and `early-init.el`.
- Keep this README aligned with the current configuration. If package usage, startup behavior, keybindings, or workflow changes, update this file in the same change.
- Do not document planned behavior as if it already exists.