Hello, I'm Alexey Bochkarev,
and I'm talking about unentangling projects
and repositories, or maybe entangling them,
depending on how you look at that.
So there's going to be a short workflow note.
I work as a researcher,
So there are 3 main components to my work,
I guess. First, I think,
so I try to come up with a new ideas that
usually results in some collection of notes I
have. Second, I try things out.
So it usually means that I write code.
And third, I communicate.
So I prepare papers, presentations,
memos, and so on and so forth.
The workflow problem I had is
sometimes all this does not really fit into a
concept of a single repository per project.
So I might want to have,
for example, a source code in one repository
and then I would like to have a paper in
another one, and then I want to have a
collection of notes somewhere unrelated to
those two. Emacs is pretty good at supporting
your workflows and I figured I should share
what I used and what works for me.
From the technical perspective,
things are pretty easy.
I use a collection of pretty standard
components of Emacs. So it's projectile, org
mode with this capture templates, and other
things. Then I sustained a collection of
nodes in something that is called org-roam,
which is essentially it's a glorified
collection of org mode files.
Then I used directory-local variables,
maybe a ctags to jump through the source
code and very, very little elisp glue to
make this all work, but that's not really
rocket science. So that's the workflow I
would like to talk about today.
So what I mean by all that,
it's pretty straightforward to make Emacs,
to make it easy to jump around a single
repository in Emacs. So if I...
Now I have Doom Emacs,
but that's not really specific to a Doom
that'll work in any Emacs configuration.
Well, key bindings might be different,
but that's not the point,
I guess, for the workflow.
So if I hit space 2 times,
I have all the list of files within my
project, right? So if I create a couple of
custom shortcuts, so if I press a magic
button, Hyper+o p... don't worry about
hyper-key. So I want it to have a modifier
key all to myself, so that would,
no program on my computer would use that
except Emacs. Emacs would use that only when
I tell it to, so I have a hyper key instead
of caps lock. That's pretty easy to do in GNU
Linux system. So when I press this magic
keys, I have a menu that's a normal key
binding. Yeah, essentially an Emacs.
And if I hit, for example,
r, I end up in a README file within this
specific repository I was sitting in,
right? So if I want to document something
real quick, I go to the README file.
Then I could go to a change log file,
right? So I have a list of changes and the
way it works usually, for example,
if I'm working in some code,
I created a couple of dummy files in there,
so I'm working in some code and then I
implemented something and I can just use the
org mode capture mechanisms to keep track of
what I want to discuss with colleagues next
time. For example, I could just hit capture
repo specific changelog entry and I
implemented a feature and I can continue
working without this context switching.
And then if I want to go to the change log,
well, it is there. And next time I talk to
the colleagues about the source code,
I can open the change log and go through
entries 1 by 1 and discuss what I haven't
implemented last time.
I could go to project-specific,
sorry, to repo-specific to-do list.
And I have list of to-dos that would leave
within a repository. And for example,
I could have a high level structure here,
work distribution between team members and
other things that sort of face outer world,
so to speak. And of course,
there are very many ways to jump through the
source code conveniently.
I ended up not using language servers. I use a
special program called ctags and so the way
it works is just I call projectile regenerate
tags and it creates the special tags file
within the repository and then I can again
run it I usually just hit a single keystroke
and here is all the symbols that are there in
my source code, regardless of the language,
right? So I can jump to the main function and
that'll be a C++ file.
Or I could go to the super function,
which I had in my Python file.
And this comes in pretty convenient if I have
a mixture of languages.
Sometimes I can have some algorithm specific
code in Julia, and then I can have some
Python glue within the same source code
repository, it makes it really convenient to
jump between all of those.
But I have a few problems here.
So just to give you a little bit of context,
for example, here is a real project that
corresponds to real paper.
I have a single note about that project where
I keep all the things related to that project
here, but that's a private note.
So for example, again,
I hit a special key that invokes my org-roam
function that gives me a menu of my notes.
And so here is the paper,
essentially. And I can have a paper timeline,
and I can have a list of all the dates what
happened to the paper with links to my email,
right? So for example if I hit this link that
will open a specific email and that doesn't
work outside of my computer,
doesn't make any sense to keep it in the
outer world facing repository,
for example. So that's something to myself,
right? Sometimes I want to have like this
list of working notes,
right, that contain like,
for example, yeah, I might produce this kind
of things for internal discussion,
right? It has some marks,
it has some margin notes and things like
that. Maybe again, health-based ideas that
may or may not end up in a repository,
in the final paper or in a source code,
but still I want to have it somewhere.
And well, long story short,
I need a project folder that would be
unrelated to the source code or to the source
code repository or to the paper itself or a
final report, right? And 1 way,
as usual, there are multiple ways to achieve
that, I suppose. And 1 way to do that is,
so I create a special folder within my
org-roam storage. So it's a special folder
outside of any repositories that got backed up
to my hard drive with certain redundancy,
but I don't really need version control,
full blown version control for that.
I'm okay with just having a couple of
backups, right? So this is the folder you see
here. So PKB stands for personal knowledge
base, and I have a folder project notes in
there, right?
How does it work?
So I have a folder per project in there,
essentially. And here I can have all the
stuff that kind of belongs to me and I do not
publish it anywhere. And then,
For example, a source code repository knows
about that folder and a paper repository
knows about that folder.
And anything else that might leave in
separate places all over my system can know
about that folder. How do I achieve that?
Well, essentially this is 1 of the use cases
for the directory local variables,
right? So for example,
how does it work from the user perspective?
So if I hit a special key,
oh, sorry, if I hit a special key,
that would be open project.
And then for example, org mode file,
right? So this is my personal notes about
EmacsConf, not specifically about this very
talk, but I can have, you know,
the house baked ideas here again,
presentation tools and things like that.
And how does that happen?
If we try to like look at the code,
the elisp magic here,
what is happening is it's just a couple of
lines of code, in fact,
so let me just press Control,
help key. And so the key I was pressing is
open project or my file.
And so what we see here,
there is a single, so it's just a call to a
find file function. So I opened that file and
there is a special function that figures out
what is the like umbrella project nose file
and that's, again, that's very easy.
So essentially if a variable describing this,
the name for that project is defined,
then I use that as my project folder name.
If not, I take the project name from the
project tile. Well, that's pretty much it.
And how do I define this variable?
Is essentially there is this magical file in
a folder called .dir-locals.el. And I just put it there.
And then whenever I go into that folder or
any of its children folders,
I get this variable defined.
And that's pretty much it.
That's how it works for me.
I guess 1 thing that I wanted to emphasize
specifically about that is of course,
it is a time tracking,
right? So what is I find especially important
when I work in something and I want to clock
time, I usually do not want this information
to be in a source code repository or in a
paper repository because other people I work
with will not be particularly happy about
that, especially if most of them do not use
Emacs and they'll see this long list of org
clocked data and that doesn't look nice in a
plain text format. So what I usually do if I
want to clock in some time and then later
analyze what I've been spending time on,
so I go to my org mode file and I go to the,
my current project to-dos and I clock in
there. And that's how it works.
So again, what comes in handy,
if I hit C-o, I just go back to the
file I jumped in into and that's I jumped
from so that's also pretty handy.
So again no no rocket science in there.
So I create a directory local variable that
helps me to figure out what umbrella project
does this particular folder belongs to.
And this way I make Emacs aware of,
for example, facts like,
so this source code belongs to that project.
And this paper, this repository with a paper
also belongs to that project.
And I can have capture templates that would
save my notes into the my private notes file
and my to-dos and go to my private note files
and so on and so forth.
So I find it pretty simple but that really
helps to reduce this context switching.
And I don't believe it allows me to save
time, but that probably helps me to stay
focused. And this is what is really
important, I believe. So thank you very much.
And if you have any comments or suggestions
to that, please do jump into the discussion.
Yeah, after the talk, thank you.