-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathREADME.org
171 lines (146 loc) · 10.4 KB
/
README.org
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
#+TITLE: ekg
* Quick intro
:PROPERTIES:
:ORG-IMAGE-ACTUAL-WIDTH: 300
:END:
The ekg module is a simple but opinionated note taking application, for emacs.
It is a substitute for such other emacs applications such as org-roam or denote.
ekg stands for /emacs knowledge graph/.
Data is completely stored in a sqlite database. Notes are organized around tags,
and you can view many notes by looking at one or more tags.
#+CAPTION: An example of viewing a tag in ekg
[[./screenshots/ekg-tag-view.jpg]]
Editing a note from one of these buffers, or capturing a new note, lets you edit
both the note's data and the text of the note itself in a buffer.
#+CAPTION: An eample of editing a note
[[./screenshots/ekg-edit.jpg]]
Additionally, [[https://youtu.be/qxa2VrseFUA][a video demonstration and explanation of ekg]] is on YouTube. This
README has some basic information, but the full information can be found on the
[[https://github.com/ahyatt/ekg/blob/develop/doc/ekg.org][manual]], which can be viewed in the Emacs info after installing.
* Design of ekg
There are a few core ideas driving the design of ekg. The first is that a title
and a tag are the same thing. This isn't unique to ekg, other tools such as
Logseq also consider tags to be equivalent to pages of the same name, although
this functionality is limited since tags can only be just one word. In org-roam,
a tag is just a tag, so you can have a note called "emacs" and a tag called
"emacs", but these are not related. ekg takes the idea a step further: there are
(mostly) no titles, only tags. So, instead of writing text in a note called
"emacs", just write a note and tag it with "emacs". There is no "title", only
tags. If you write another note about emacs, also tag it "emacs", and maybe
something else too. Or tag it something more involved, like an idea: "emacs's
power derives from putting all data in buffers, and making all commands deal
with buffers." That's a perfectly fine tag, and if you notice a connecting idea,
you can tag it with this as well.
The advantage of this method is that it solves something that has bothered me
for a while about the recent suite of tools like org-roam: backlinks are
non-symmetrical. If you enter a note in your org-roam daily about emacs, and
link it to the emacs note, then when you go to the emacs note, you have to
explicitly enable the backlinks buffer to see the daily entry where you first
entered it. Systems such as Logseq and the original Roam have backlinks
alongside normal content, but this doesn't seem possible in emacs, where a
buffer of a file is expected show the file, and tricks with overlays can't solve
the issue. Even if it could, I want a system in which it doesn't matter where
you enter the data, it shows up in the original place the same as everywhere
else it is linked to, not as a backlink, but just as part of the content. Having
notes with no title, only tags, makes this possible, because there is no longer
a difference between linking and writing in the context in, both are denoted by
tags.
As a consequence of this design, notes can be small, because to add another note
to a subject, you don't need to append to an existing note, you can create
another note.
Additionally, ekg has another key difference: it uses =sqlite= instead of the
filesystem. When notes are small and do not have titles, files don't make a lot
of sense anymore. Additionally, the filesystem is limited. Even in org-roam,
which uses it, it needs to be augmented with sqlite anyway to enable fast
querying of tags and other operations. The sqlite-only approach also means it is
much easier to make certain kinds of changes, since they only involve changing
the database and not the text as well. In general, text and data are separated
as much as possible here, so there's no need or desire for the text to have to
store data as well, we leave that completely to the database.
* Prefixed tags
Another concept, loosely applied in ekg is that of tags with standard prefixes.
By default, date tags are prefixed with "date/". This is a way to distinguish
date tags from other kinds of tags. Most tags shouldn't need it, but it often is
useful to have prefixes to group tags in some way. For instance, perhaps all
idea tags should be prefixed with "idea/". In my ekg repository I use in my
company, I have "person/" as a tag prefix for my coworker's username.
The benefit of this is that it's now possible to narrow in on just tags of a
certain type if necessary.
There are a few other types of prefixes commonly used for tags. One is that
titled resources have default tags that are prefixed with "doc/", followed by
the name of the document. Removed tags are prefixed with "trash/", but these are
normally invisible to the user. There's a section on these trash tags below
which goes into more detail.
* Warning
ekg is a fairly new package, and as such, there may be significant bugs. Testing
is done, but this package has not yet had the wide use that will surface many
kinds of bugs.
* Installation
ekg is currently hosted on MELPA. It requires Emacs 28.1 or higher and the
[[https://github.com/ahyatt/triples][triples]] package, which is a way to express a graph in sqlite in emacs, alongside
basic querying functionality. Emacs versions prior to version 29 are dependent
on =emacsql= to provide sqlite functionality, which itself has a dependency on
having a =sqlite= binary available on your system.
An example installation using =use-package= is below:
#+begin_src emacs-lisp
(use-package ekg
:bind (([f11] . ekg-capture)))
#+end_src
* Usage
To create a note, run =ekg-capture= to capture a text note, or =ekg-capture-url= to
capture a website. The note will, by default, be tagged with the current date.
This can be changed by changing the variable ~ekg-capture-auto-tag-funcs~, which
is a series of functions that are called and can add tags.
At the top of the note is a special section, which will be unfamiliar. This is
the metadata section, where it stores and displays editable metadata, notably
tags, but possibly other data such as URLs. If you want to change tags, just
edit them in the metadata section. Tags should autocomplete based on the
tags available to use.
The basic read operation in ekg is to show a list of notes according to some
rule. An example is =ekg-show-notes-with-tag=. The notes displayed can be
navigated between using =n= and =p=, and interacted with. The following section has
a complete list of commands and keybindings.
* Command summary
Global commands, can be run everywhere, and most should be bound to useful keybindings:
| Command | Description |
|--------------------------------+---------------------------------------------------------------------|
| =ekg-capture= | Capture a new note |
| =ekg-capture-url= | Capture a new note about a URL |
| =ekg-show-notes-with-tag= | Open a tag buffer for notes matching the single tag given |
| =ekg-show-notes-with-any-tags= | Open a tag buffer for notes matching any of the given tags |
| =ekg-show-notes-with-all-tags= | Open a tag buffer for notes matching all of the given tags |
| =ekg-show-notes-in-trash= | Open a tag buffer that shows all notes with only trashed tags |
| =ekg-show-notes-for-today= | Open a tag buffer that shows notes with today's tag |
| =ekg-show-notes-latest-captured= | Open a buffer that shows the latest notes that have been captured |
| =ekg-show-notes-latest-modified= | Open a buffer that shows the latest notes that have been modified |
| =ekg-browse-url= | Open a URL stored as a resource to a note, completing by note title |
These are also global commands, but for more occasional or specialized uses:
| Command | Description |
|----------------+------------------------------------------------------------|
| =ekg-rename-tag= | Rename a tag, updating all references to it |
| =ekg-upgrade-db= | After upgrading, update any obsoletely stored data |
| =ekg-clean-db= | Remove unused data from the database, including empty tags |
Commands relevant to capture buffers:
| Command | Description |
|-------------------------+------------------------------------|
| =ekg-capture-change-mode= | Change note major-mode |
| =ekg-capture-finalize= | Finish and save (bound to =C-c C-c=) |
Commands relevant to edit buffers:
| Command | Description |
|-------------------+------------------------------------|
| =ekg-edit-finalize= | Finish and save (bound to =C-c C-c=) |
Commands relevant to tag buffers:
| Command | Description | Binding |
|---------------------------------+---------------------------------------------------------------------------+---------|
| =ekg-notes-tag= | Open another tag buffer selecting from tags of current note | =t= |
| =ekg-notes-open= | Edit the currently selected note | =o= |
| =ekg-notes-delete= | Delete the currently selected note | =d= |
| =ekg-notes-remove= | Remove the tag buffer's tags from the currently selected note | =r= |
| =ekg-notes-browse= | Open the resource, if one exists | =b= |
| =ekg-notes-select-and-browse-url= | Select from the URLs in the current note buffer, and browse. | =B= |
| =ekg-notes-refresh= | Refresh the tag, refetching all the data displayed | =g= |
| =ekg-notes-create= | Add a note with all the tags displayed in the buffer | =c= |
| =ekg-notes-next= | Move selection to the next note | =n= |
| =ekg-notes-previous= | Move selection to the previous note | =p= |
| =ekg-notes-any-note-tags= | Open another tag buffer showing any of the tags in the current note | =a= |
| =ekg-notes-any-tags= | Open another tag buffer showing any of the tags in any note in the buffer | =A= |