this-month-in-org/2022-02-30-orgnvim.txt

413 lines
17 KiB
Plaintext
Raw Normal View History

2024-01-09 18:20:48 +00:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FEBRUARY 2022
An orgmode clone for neovim
Kristijan Husak
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2022-02-30
Timothy (TEC) here. This month we have a guest post from a different
part of the Org ecosystem, to highlight one of the most promising
efforts to provide a good experience outside Emacs.
//github.com/nvim-orgmode/orgmode
2024-01-12 05:40:29 +00:00
“But I use Emacs, I dont care” you may say. In that case, Id like to
2024-01-09 18:20:48 +00:00
point out that wider spread and better Org support enriches the Org
2024-01-10 17:36:58 +00:00
ecosystem as a whole. It makes the format more approachable, and
2024-01-09 18:20:48 +00:00
/useful/ for other people. This is good for everybody.
2024-01-12 05:40:29 +00:00
Without any further ado, heres the guest post kindly written by
2024-01-10 17:36:58 +00:00
Kristijan. Enjoy!
2024-01-09 18:20:48 +00:00
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Like every beginner Vim user, at some point I ran into a usual editor
2024-01-12 05:40:29 +00:00
war post: Vim vs Emacs. At that time, I didnt have an idea what “Emacs”
2024-01-09 18:20:48 +00:00
was.
A simple Google search yielded something that seemed just like a very
2024-01-12 05:40:29 +00:00
simple editor with strange, but more familiar shortcuts. I didnt bother
2024-01-09 18:20:48 +00:00
too much to figure out what it is, because I was already pulled in
fairly deep into Vim and its philosophy.
Note taking in (Neo)Vim
═══════════════════════
At first, I did some note taking only when really necessary, in random
plain text files. Most of the things I managed to keep in my head,
since I was younger and less busy 🙂.
Once I got into the situation where I needed to keep more notes,
[vimwiki] was the natural choice.
That worked very well for a period, until the need for writing quick
2024-01-12 05:40:29 +00:00
notes arise. Vimwiki didnt have anything that would allow that. I
2024-01-09 18:20:48 +00:00
could of course have a mapping that opens a specific file where I can
add notes, but that just never felt right in my mind. I would keep a
bunch of things in the same place, and then later I needed to spend
some time organizing them.
2024-01-12 05:40:29 +00:00
At that point, I wasnt sure how to achieve what I want. I did a brief
look at [Emacs OrgMode] to see whats all the fuss about, but to me,
2024-01-09 18:20:48 +00:00
it seemed just like a different version of Markdown. You put some
2024-01-12 05:40:29 +00:00
unordered lists as your notes, and thats it. I never spent more time
2024-01-09 18:20:48 +00:00
trying to see all the neat features. I even tried creating some of my
custom note taking tools, but I never managed to finish them because I
2024-01-12 05:40:29 +00:00
didnt have a clear idea of how to solve my problems.
2024-01-09 18:20:48 +00:00
[vimwiki] <https://github.com/vimwiki/vimwiki>
[Emacs OrgMode] <https://orgmode.org/>
First encounter with Orgmode like tool: vim-dotoo
═════════════════════════════════════════════════
One weekend, I was browsing through Vim subreddit, as I usually do at
2024-01-12 05:40:29 +00:00
least once a day. There was a post about an “Orgmode like task
logging” plugin called [vim-dotoo]. I opened it up, and I didnt see
much at that point. I wasnt too excited. I went through readme, and
2024-01-09 18:20:48 +00:00
noticed that author ([dhruvasagar]) put a fairly big emphasis on the
2024-01-12 05:40:29 +00:00
“Agenda view”. I had no idea what “Agenda view” is. Thankfully, the
2024-01-09 18:20:48 +00:00
author also made a [screencast], which is rather long (1.5h), but I
had some time, so I went through it.
2024-01-12 05:40:29 +00:00
At that point, I was first met with “Capturing” and “Refiling”. *My
2024-01-09 18:20:48 +00:00
mind was blown!* What a simple, yet extremely powerful idea! How had
that never crossed my mind? From that point on, this plugin had my
full attention.
2024-01-12 05:40:29 +00:00
Im always emphasizing that [dhruvasagar] and his [vim-dotoo] plugin
2024-01-09 18:20:48 +00:00
are most deserving for having inspired
2024-01-12 05:40:29 +00:00
<https://github.com/nvim-orgmode/orgmode>, and I cant thank him
2024-01-09 18:20:48 +00:00
enough for that.
[vim-dotoo] <https://github.com/dhruvasagar/vim-dotoo>
[dhruvasagar] <https://github.com/dhruvasagar>
[screencast] <https://www.youtube.com/watch?v=nsv33iOnH34>
First steps with vim-dotoo and birth of orgmode.nvim
════════════════════════════════════════════════════
For some time, I was using [vim-dotoo]. I moved all of my Vimwiki
notes to it. It was a breath of fresh air. Alongside that, I started
getting more interest in the original Emacs Orgmode. I started
noticing the differences, and some of the missing features that were
2024-01-10 17:36:58 +00:00
now looking quite attractive. I made [few contributions] to
vim-dotoo. As time passed, and my notes started to grow, things began
2024-01-12 05:40:29 +00:00
being slow. I did some profiling, and figured out that its just a
2024-01-10 17:36:58 +00:00
usual Vim problem, Vimscript performance. It was just too slow for
certain things that Orgmode provides, and it would hardly get any
better as more things are added.
2024-01-09 18:20:48 +00:00
Separately from Vim and Vimscript, [Neovim] was on a stable `v0.4'
release, and `v0.5' was still being developed. I was using Neovim from
version 0.3, and was carefully following the progress on it. Lua was
introduced as a first class citizen. A Bunch of new plugins arise from
it. All the benchmarks showed that Lua outperforms Vimscript in almost
2024-01-12 05:40:29 +00:00
everything. Besides the performance, Lua is a “normal” programming
2024-01-09 18:20:48 +00:00
language, which means that support for it is much better.
At that point, I became curious: Could Lua be the path to the faster
Orgmode? I spent several days thinking about it. I wanted to give it a
try. My biggest concern was that I had absolutely zero experience
writing parsers. I had never written anything more complicated than an
averagely complicated regex for purposes of parsing. I noticed that
vim-dotoo also used regex to do the parsing, so that eased my mind a
bit.
One weekend, I started working on it. It was really interesting and
2024-01-10 17:36:58 +00:00
challenging. I spent a lot of my free time on it. At certain points,
2024-01-09 18:20:48 +00:00
it seemed like hacking, since it was not a proper parsing. I tried to
learn how to write a proper parser, but it was just too time consuming
and complicated. I proceeded with the regex parsing to see how far I
can go.
Besides parsing, I had a few more challenges to overcome:
[vim-dotoo] <https://github.com/dhruvasagar/vim-dotoo>
[few contributions]
<https://github.com/dhruvasagar/vim-dotoo/pulls?q=is%3Apr+sort%3Aupdated-desc+author%3Akristijanhusak+is%3Aclosed>
[Neovim] <https://github.com/neovim/neovim>
Understanding the OrgMode syntax and all the functionality
──────────────────────────────────────────────────────────
2024-01-12 05:40:29 +00:00
This is still the biggest challenge. I didnt have any idea how big
and robust OrgMode is. If I would know it at that time, I wouldnt
even jump on this train. Its really hard to grasp all of
it. Considering Ive only used it for around 8 months, I think I made
2024-01-10 17:36:58 +00:00
some good progress on learning it.
2024-01-09 18:20:48 +00:00
Remote editing
──────────────
By remote editing, I mean automatically updating content in the
current or any other file. Few examples: adding/updating properties,
managing tags, changing TODO states, archiving, refiling, remote
editing from agenda view, etc.
There is no built-in way to update content in another file through the
Neovim API, without actually opening the file in an editor. I solved
this by:
• Saving as much position information as possible in the internal
state, so I can pinpoint the correct location
• Opening a file in a `1 row x 1 col' floating window and doing quick
edits there
Working with dates
──────────────────
From my experience, dates are challenging in all areas of programming,
so this is not so surprising. There are some Lua plugins for dates,
but those seemed a bit too basic for my use case, and I wanted to keep
external plugins to the minimum. I went with a custom solution that
2024-01-12 05:40:29 +00:00
uses Luas native dates, which has certain limitations, but works out
2024-01-09 18:20:48 +00:00
for most of the things.
Highlighting, mostly in Agenda view
───────────────────────────────────
2024-01-12 05:40:29 +00:00
Vims syntax engine is fairly old, but still very much used,
2024-01-09 18:20:48 +00:00
especially in the Vim community. Implementation of tree-sitter
2024-01-12 05:40:29 +00:00
slightly improved this experience in Neovim, because “Highlight
matches” are found via tree-sitter, instead of a bunch of regexes.
2024-01-09 18:20:48 +00:00
This helped me out later for the Org file itself, but agenda view is
2024-01-12 05:40:29 +00:00
still something thats built as a custom view. Old Syntax highlight
2024-01-09 18:20:48 +00:00
engine would be really hard to add, because the content is too
dynamic. I went with the Neovim highlight API that allows Highlighting
things by their exact position in the buffer. Tree-sitter
implementation does something similar in the background for
Highlighting.
Keeping configuration simple and familiar to Emacs OrgMode
──────────────────────────────────────────────────────────
Vim-dotoo configuration was mostly Vim style, through some global
variables. I wanted to have a configuration that is familiar to an
Emacs OrgMode user, by having as many options as possible named
completely the same as in Emacs.
2024-01-12 05:40:29 +00:00
For example, Heres a comparison of few options between Emacs and
2024-01-09 18:20:48 +00:00
Neovim:
Emacs:
┌────
│ (setq org-agenda-files '("~/orgmodes"))
│ (setq org-agenda-skip-scheduled-if-done t)
│ (setq org-agenda-span 7)
│ (setq org-hide-leading-stars t)
│ (setq org-capture-templates
│ '(("t" "Todo" entry (file "~/orgmodes/todos.org")
│ "* TODO %?")
│ ("j" "Journal" entry (file "~/orgmodes/journal.org")
│ "* %?\nEntered on %U\n %a")))
└────
Neovim:
┌────
│ require('orgmode').setup({
│ org_agenda_files = { '~/orgmodes' },
│ org_agenda_skip_scheduled_if_done = true,
│ org_agenda_span = 7,
│ org_hide_leading_stars = true
│ org_capture_templates = {
│ t = {
│ description = 'Todo',
│ target = '~/orgmodes/todos.org',
│ template = '* TODO %?',
│ },
│ j = {
│ description = 'Journal',
│ target = '~/orgmodes/journal.org',
│ template = '* %?\nEntered on %U\n %a',
│ }
│ }
│ })
└────
One of the most noticeable differences is between the usage of hyphens
(`-') and underscores (`_'). I did that only for the sake of
simplicity, because hyphens is not a valid character in variable names
in Lua, so all of the options would need to be wrapped as a string
(for example: `['org-agenda-files']').
First release of orgmode.nvim and introduction of tree-sitter parser
════════════════════════════════════════════════════════════════════
After ~1.5 months I [published the initial version]. The focus was on
2024-01-10 17:36:58 +00:00
Agenda and capturing (GTD), since those are the things I mostly
used. It got some traction, and people started testing it and
reporting bugs.
2024-01-09 18:20:48 +00:00
2024-01-12 05:40:29 +00:00
One of the common questions was: /“Any plans to introduce tree-sitter
parser?”/.
2024-01-09 18:20:48 +00:00
I knew about [tree-sitter] and used it in my day-to-day job for a few
programming languages, but I had absolutely no idea how it worked, and
especially how to write a tree-sitter parser. I put it aside, and
continued working on what I had.
One day, Emilia ([milisims]) contacted me via email to ask me if I
2024-01-12 05:40:29 +00:00
would be willing to try the tree-sitter parser shes been working on
2024-01-09 18:20:48 +00:00
for some time. I gladly accepted. She gave me access to the
repository, and I started tinkering with it in a separate branch. No
one was aware at that point that tree-sitter support would happen some
time soon.
2024-01-12 05:40:29 +00:00
After some time, I set up a “beta” branch called “tree-sitter” and
2024-01-09 18:20:48 +00:00
[announced it for testing]. Once the reported bugs slowed to a
2024-01-12 05:40:29 +00:00
trickle, I merged it into the “master” branch.
2024-01-09 18:20:48 +00:00
I believe that tree-sitter grammar for Org could help out other
2024-01-12 05:40:29 +00:00
editors to implement their version of Orgmode plugin, but I dont
2024-01-09 18:20:48 +00:00
think it would ever be helpful for Emacs. Emacs parser is the one and
2024-01-10 17:36:58 +00:00
only that has it all implemented. Also, as much as tree-sitter is
2024-01-09 18:20:48 +00:00
powerful, its main purpose is to parse programming languages, which
2024-01-12 05:40:29 +00:00
mostly has “static” patterns to match. Orgmode is by its nature
dynamic, which causes a variety of issues for a parser thats not
2024-01-09 18:20:48 +00:00
meant for that kind of usage.
[published the initial version]
<https://www.reddit.com/r/neovim/comments/o8zp0k/orgmodenvim_orgmode_clone_written_in_lua_for/>
[tree-sitter] <https://github.com/tree-sitter/tree-sitter>
[milisims] <https://github.com/milisims>
[announced it for testing]
<https://www.reddit.com/r/neovim/comments/ph2xqc/orgmodenvim_treesitter_support/>
Limitations
═══════════
(Neo)Vim is a great editor, but it still cannot compare to Emacs in
2024-01-12 05:40:29 +00:00
certain things. Manipulating the “View” part of the editor is tricky
2024-01-09 18:20:48 +00:00
or impossible for certain things.
I even [made a label] for reported issues where Neovim support for
2024-01-12 05:40:29 +00:00
certain things is a blocker. Im hoping that at least some of these
2024-01-09 18:20:48 +00:00
will be available in future Neovim releases.
[made a label]
<https://github.com/nvim-orgmode/orgmode/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aneovim-dependency>
Features
════════
I will not go into too many details about the available features,
since those can be viewed in [repository readme], but I want to
mention one feature that does not exist as a built/-in feature in the
Emacs Orgmode: [Notifications].
2024-01-12 05:40:29 +00:00
This allows getting a “desktop notification” for tasks that are within
2024-01-09 18:20:48 +00:00
the specified threshold for schedule/deadline time. It requires some
2024-01-12 05:40:29 +00:00
configuration to set up a cron job, but its been working great for me
2024-01-09 18:20:48 +00:00
for several months now.
[repository readme]
<https://github.com/nvim-orgmode/orgmode#features-detailed-breakdown>
[Notifications]
<https://github.com/nvim-orgmode/orgmode/blob/master/DOCS.md#notifications-experimental>
Plans
═════
2024-01-12 05:40:29 +00:00
The current state of the project is very usable for me. Im not
lacking any of the major features, mostly because Im not used to
using them. Nevertheless, there are plans to add more things, and Im
2024-01-09 18:20:48 +00:00
getting a lot of help from the community. I want to specifically
mention [levouh] and [lukas-reineke], since they added a lot of value
to the project, and I want to thank them and everyone else who
contributed. Their help is much appreciated.
2024-01-12 05:40:29 +00:00
There are few high priority tasks that Im hoping to flush out first:
2024-01-09 18:20:48 +00:00
• Implementing [v1.0.0] release of the tree-sitter parser. This should
allow for faster and less error-prone parsing.
• [Infrastructure for plugin developers], to allow other people to
build plugins on top of nvim-orgmode.
And a long term goal for these:
• Tables support (and at least basic formulas)
• [Org Babel like code block evaluation] (and hopefully basic support
for literate programming)
• [Diary format dates]
• [Custom agenda commands]
• More clocking features (reports)
• File specific configuration via directives ([todo keywords],
properties, etc.)
[levouh] <https://github.com/levouh>
[lukas-reineke] <https://github.com/lukas-reineke>
[v1.0.0] <https://github.com/milisims/tree-sitter-org/issues/13>
[Infrastructure for plugin developers]
<https://github.com/nvim-orgmode/orgmode/issues/26>
[Org Babel like code block evaluation]
<https://github.com/nvim-orgmode/orgmode/issues/190>
[Diary format dates]
<https://github.com/nvim-orgmode/orgmode/issues/195>
[Custom agenda commands]
<https://github.com/nvim-orgmode/orgmode/issues/135>
[todo keywords] <https://github.com/nvim-orgmode/orgmode/issues/185>
Closing thoughts
════════════════
2024-01-12 05:40:29 +00:00
When I started working on [nvim-orgmode], I didnt have a clue what
Im jumping into. Every day I learn about more and more Orgmode
features that I wasnt even aware existed.
2024-01-09 18:20:48 +00:00
2024-01-12 05:40:29 +00:00
Im certain that this project will never manage to clone the Orgmode
functionality completely, but Im hoping it will get close enough so
2024-01-09 18:20:48 +00:00
everyone from Neovim community and Emacsers trying out Neovim will be
able to use it for their needs.
Having experienced Orgmode users [testing] it is a huge help, so if
anyone is willing to give it a try, feel free to open up an issue and
write your thoughts there. Thanks!
[nvim-orgmode] <https://github.com/nvim-orgmode/orgmode>
[testing] <https://github.com/nvim-orgmode/orgmode/issues/159>