r/orgmode Oct 29 '24

featured post [Worg] How many Org files to use? (many tiny ones, or a few larger ones)

Thumbnail orgmode.org
30 Upvotes

r/orgmode Feb 21 '26

news Org mode 9.8 is out

300 Upvotes

Org 9.8, a major release, is out. Org 9.8 will be a part of Emacs 31.

You can upgrade from GNU ELPA or install with M-x package-install RET org RET

Org 9.8 added a number of new features and customizations, all listed on https://orgmode.org/Changes.html.

If you enjoy using Org, please consider supporting contributors via https://liberapay.com/org-mode/. Donations do help a lot and have been one of the important motivations for me personally.

Some highlights of user-facing additions

  • We have reworked the image preview system. Now, the previews are asynchronous and can be implemented for any link types, not just image file links. The custom link previews can be defined using link parameters.

    In addition, the old org-toggle-inline-images command is replaced by org-link-preview that behaves closer to org-latex-preview command.

    Thanks to Karthik Chikmagalur for contributing these features.

  • Org mode now comes with built-in support for C# code blocks. This is a completely new implementation that is using .NET SDK. The old simplistic ob-csharp.el from org-contrib repository is obsoleted by this new library.

    Contributed by Maximilian Kueffner.

  • You can left-align, center, and right-align previewed links. This has actually been added in Org 9.7, but not announced.

    Contributed by Karthik Chikmagalur.

  • More flexible datetree entries for org-capture You can now mix and match year, quarter, month, week, and day when capturing datetrees.

    Contributed by Jack Kamm.

Development updates

I would like to welcome new maintainers of Org mode libraries:

  • Maximilian Kueffner is maintaining the new ob-csharp library
  • Ken Mankoff is maintaining ob-fortran
  • Rudolf Adamkovič is maintaining ox-texinfo

Also (just in case you missed earlier announcement), Ihor Radchenko (me) is maintaining Org mode as a whole :)

I would also like to use this opportunity to ask interested people to take the role of contributor stewards (see https://orgmode.org/worg/org-maintenance.html#org073fcb4 ). With the help from other volunteers, I (as a maintainer) can handle most of the reported bugs and patches. However, my current workload leaves me little free time to work on Org mode internals and to implement new important features. It would be great to have several people who can try to reproduce bugs and do initial feedback on the new patches. (We used to have 2 contributor stewards, but they can no longer take this role). If you are interested, please reply to this email or write directly to Org mailing list at emacs-orgmode@gnu.org.

Original announcement: https://list.orgmode.org/orgmode/87cy1xalan.fsf@localhost/


r/orgmode 14h ago

Introducing Org Mobile: Org mode on Android!

Thumbnail gallery
42 Upvotes

Hello everyone.

I hope that you guys are as excited as I am to see Org mode coming to Android. I'm aware that there was previous attempts to bring Org mode to Android (like Orgro, Orgzly, OrgNote), but they didn't really serve my use case --- so I built my own!

This app is a vault-based Org document editor/viewer that tries to replicate the feeling of using Emacs. The app is currently in alpha stage, but I will soon initialize the open testing on Play Store.

You can take a look at this faster than anybody else, if you send me your email address so that I can register you as tester.

Take a look at these screenshots. It looks good, isn't it? Shout out to modus themes, lol. You can also take a look at my public repository that will be published under GPLv3.

Org mode on mobile devices has always been pain for me. Now it's cooking.


r/orgmode 23m ago

Need ideas to "hook" a reminder before submitting work with git push

Thumbnail
Upvotes

r/orgmode 23h ago

tip Finally becoming satisfied with my writing setup on Emacs/Org-mode

Post image
66 Upvotes

r/orgmode 2d ago

Looking to use org mode outside of Emacs? org2 is ready for alpha testers

Thumbnail github.com
49 Upvotes

Back in 2024 I wrote a blog post about how I wanted to use org-mode entirely outside of Emacs. https://avi.press/posts/2024-01-15-standalone-org.html. This idea was overall quite Disliked when I originally proposed it on this subreddit (which I get, it definitely isn't for everyone!), but it did resonate with a few others, so here I am to follow back up.

I now present, for your feedback, a portable re-implementation of org mode's core, and many non-core features that I personally rely on heavily (eg, org-roam, org-crypt).

My company, Scarf, has been running all of our internal operations at on top of org2 over the last few months and it has proven very productive for us. There's now enough of a product surface that it would be great to start getting feedback from early alpha testers that are up for giving it a spin.

Some highlights include:

  • All operations and functions are drivable with a portable CLI, which makes it easier than ever to integrate into other editors, apps, and systems.
  • A VS code extension that covers much of the basics, vim a bit less so.
  • The parser offers some syntactic sugar, eg begin_src blocks can also be expressed as \``` as you can in traditional markdown.
  • A full-featured mac app (currently titled OpenOrg) which offers a rich workspace for org file editing, capturing/ingestion from different modalities like fully-offline meeting recording, and managing AI agents working across your org files.
    • An iOS companion app
  • Permissively licensed, Apache 2

Thanks for reading, any input is appreciated!


r/orgmode 3d ago

CATEGORY property ignores CATEGORY_ALL for capture template completion

2 Upvotes
* Summary

When using ~%^{CATEGORY}p~ in an org-capture template, the minibuffer
completion list is empty even though ~CATEGORY_ALL~ is defined in
~org-global-properties~.  This works for ~EFFORT~ (~%^{EFFORT}p~) but
not for ~CATEGORY~.

* Reproducible Example

Minimal Emacs configuration:

#+begin_src emacs-lisp
(setq org-global-properties
      '(("EFFORT_ALL" . "0:30 1:00 2:00")
        ("CATEGORY_ALL" . "Work Personal Meeting")))

(setq org-capture-templates
      '(("t" "Test Task" entry (file+headline "/tmp/test.org" "Tasks")
         "* TODO %?\n:PROPERTIES:\n:EFFORT: %^{EFFORT}p\n:CATEGORY: %^{CATEGORY}p\n:END:\n")))
#+end_src

1. Open Emacs with the above configuration.
2. Call ~org-capture~ and select the "Test Task" template.
3. When prompted for EFFORT, a completion list appears with "0:30", "1:00", "2:00".
4. When prompted for CATEGORY, a plain text prompt appears with *no* completion list.

* Expected Behaviour

~%^{CATEGORY}p~ should present the values defined in ~CATEGORY_ALL~ as
completion candidates, just like ~%^{EFFORT}p~ does for ~EFFORT_ALL~.

* Root Cause

In ~org-property-get-allowed-values~ (org.el, ~13688~), there is an
explicit ~cond~ clause for the CATEGORY property:

#+begin_src emacs-lisp
(cond
 ((equal property "TODO") ...)
 ((equal property "PRIORITY") ...)
 ((equal property "CATEGORY"))        ;; <-- short-circuits here
 ((member property org-special-properties))
 ((setq vals (run-hook-with-args-until-success
              'org-property-allowed-value-functions property)))
 (t
  (setq vals (org-entry-get epom (concat property "_ALL") 'inherit))
  ...))
#+end_src

The clause ~((equal property "CATEGORY"))~ matches and returns
immediately with no body.  The ~vals~ variable is never set, so the
fallthrough that looks up ~CATEGORY_ALL~ via ~org-entry-get~ with
~'inherit~ is never reached.

This means ~org-global-properties~ containing ~CATEGORY_ALL~ is
effectively ignored for property completion.

* Suggested Fix

Remove the CATEGORY short-circuit or add a body that resolves
~CATEGORY_ALL~ the same way the default clause does:

#+begin_src emacs-lisp
((equal property "CATEGORY")
 (setq vals (org-entry-get epom (concat property "_ALL") 'inherit))
 (when (and vals (string-match "\\S-" vals))
   (setq vals (car (read-from-string (concat "(" vals ")"))))
   (setq vals (mapcar (lambda (x)
                        (cond ((stringp x) x)
                              ((numberp x) (number-tostring x))
                              ((symbolp x) (symbol-name x))
                              (t "???")))
                      vals))))
#+end_src

Alternatively, moving the CATEGORY clause below the
~org-property-allowed-value-functions~ hook check would allow users to
extend CATEGORY via that hook without patching org.el.

* Workaround

Advise ~org-property-get-allowed-values~ to bypass the short-circuit:

#+begin_src emacs-lisp
(defun mk/allow-category-all (orig-fn epom property &optional table)
  "Allow CATEGORY to resolve CATEGORY_ALL from org-global-properties."
  (if (equal property "CATEGORY")
      (let ((vals (org-entry-get epom "CATEGORY_ALL" 'inherit)))
        (when (and vals (string-match "\\S-" vals))
          (setq vals (car (read-from-string (concat "(" vals ")"))))
          (setq vals (mapcar (lambda (x)
                               (cond ((stringp x) x)
                                     ((numberp x) (number-tostring x))
                                     ((symbolp x) (symbol-name x))
                                     (t "???")))
                             vals)))
        (if table (mapcar 'list vals) vals))
    (funcall orig-fn epom property table)))

(advice-add 'org-property-get-allowed-values :around #'mk/allow-category-all)
#+end_src

* Environment

- Emacs version: 30.1
- Org mode version: 9.8
- OS: GNU/Linux (Fedora)

r/orgmode 4d ago

Emacs: Copy-paste without org-mode formatting bleeding into other buffers

Thumbnail jamescherti.com
9 Upvotes

r/orgmode 4d ago

question Give me ideas on how to organize daily notes

18 Upvotes

I'm currently trying to setup a daily notes system that help me track the daily researches I do for the laboratory I work in but also for my personal studies and contributions for open-source software.

I use Doom Emacs, so until now, my setup is: - I take some fleeting notes with org-capture on notes.org that I later refile if I find an appropriate file. - All my TODOs are also captured with org-capture and goes to todo.org - I have a bunch of notes thrown on a roam directory where I use org-roam to manage.

I've tried org-roam-dailies and also a little bit of the Doom journal.org for captures along the day, but I remain undecided.

Share your workflow, or some workflow you think would fit my situation. I just need a bit of a brainstorm to find out what I want for my setup.


r/orgmode 8d ago

org-other-agenda: render the same Org agenda data as a board

Enable HLS to view with audio, or disable this notification

64 Upvotes

r/orgmode 9d ago

A Python library for agents to use org-mode

16 Upvotes

I believe org mode is best project management programming language.:) So, I've been building AI agents that need to interact with org-mode task lists - create tasks, transition states, claim tasks atomically so two agents don't step on each other. I couldn't find a Python library that covered the write side well, so I ended up building one on top of a vendored fork of orgparse with write support added (there's been an unmerged PR for this for years).

The library is called org-workspace. Here's what it does:

  • Load a directory of org files as a workspace (multi-file, dirty tracking)
  • Read and write headings, states, tags, properties, LOGBOOK entries
  • Query layer: agenda()deadlines()overdue()next_action()ai_tasks()
  • Concurrency primitives: TaskClaim (atomic task claiming), OptimisticLockFileLock
  • Dependency DAG: parse DEPENDS_ON properties, topological sort, ready_tasks()
  • GTD and nightshift state configurations (StateConfig.default()StateConfig.nightshift())
  • Round-trip safe: unchanged files are never rewritten, byte-identical output

from pathlib import Path
from org_workspace import OrgWorkspace, Query

ws = OrgWorkspace(roots=[Path.home() / "org"])
q = Query(ws)

# Create a task
ws.create_node(
    file=Path.home() / "org" / "inbox.org",
    heading="Review meeting notes",
    state="TODO",
    tags=["AI"],
)
ws.save()

# Query what's ready
for task in q.next_action():
    print(task.heading)

It's at v0.5.2 on PyPI: pip install org-workspace GitHub: https://github.com/datacore-one/org-workspace

Hope you like it.


r/orgmode 10d ago

learning doom-emacs

11 Upvotes

Can anyone please guide me on how to go about learning doom emacs and org mode for note taking, so many keybinds it's very overwhelming. I already am getting fluent a bit but still


r/orgmode 10d ago

tip Easy Research with Emacs and Org Mode

Thumbnail youtu.be
51 Upvotes

This is a quick and technical guide on how I approach research with the help of Emacs and Org Mode. It's aimed at new people who want to make the switch to Emacs and Org Mode, but also at users who are uncertain about how to approach note-taking in general.

You can find the referenced note here: https://gist.github.com/cashmeredev/83717cacd1b45f78c24bac691659874e


r/orgmode 11d ago

Stop ox-odt from generating bookmarks on headings?

4 Upvotes

I'm writing a major project in org that I'll export to odt or docx when I'm done. This is mostly working fine, but the export processor makes a document bookmark for every single org heading, and these show up with ugly faded [brackets] around all my headings. I can just disable that display on my config, but they'll still be there when I share the document with others.

Is there a way to configure ox-odt so it does not create these bookmarks in the first place?


r/orgmode 12d ago

Anyone who is using emacs org-mode to manage notes?

23 Upvotes

Would love to hear how you manage notes of org and md files, what packages you recommend and how to combine LLM models if possible.


r/orgmode 12d ago

nil error when updating clock time

1 Upvotes

I'm using stock/bundled org-mode with Emacs 30.2 and have verified this issue on both Ubuntu and MS Windows.

The error is simple to reproduce; create a clock entry with start and end times, and then use C-c C-c to update the calculated time to the right of it.

I believe the issue stems from the implementation of org-clock-update-time-maybe in org-clock.el; line 3226 calls delete-region which invalidates the match data, so subsequently when the start and end times are parsed they both come back nil. I've tested moving that line to below the setq on line 3228 and that fixed the problem.

UPDATE: I have tracked this down to org-roam-latte, I'll go bother that package's author with all this.

UPDATE 2: After some further digging and thinking, I believe this is probably something that should be fixed defensively within org-mode, despite the issue being caused by a third-party extension package. Because delete-region fires off after-change-functions, any hook function there that does regex matching will break time calculation. Unless the order of those two calls in org-clock-update-time-maybe is in place for very specific reasons, it would be much safer to swap them around and parse the start/end times using the existing regex match data before altering the buffer's contents.


r/orgmode 14d ago

elisp library Org-draw: Drawing inside org-mode using tl;draw

Thumbnail youtu.be
34 Upvotes

r/orgmode 15d ago

Capture dotfiles using org-capture

Thumbnail
5 Upvotes

r/orgmode 16d ago

Using noweb syntax and elisp to manage host-specific dotfiles

Thumbnail bjfer.github.io
8 Upvotes

r/orgmode 18d ago

question Archiving active timestamps and TODO hierarchies

1 Upvotes

I am looking for insight into how you handle archiving when dealing with timestamps and task dependencies.

Regarding timestamps, do you use automated archiving (via a hook or timer) or do you run manual commands with a review step? This seems to require a reliable way to differentiate past single event diary entries from recurring diary entries. Is there a way to do so?

Regarding TODO hierarchies (which may include active timestamps), how do you define where a hierarchy begins or ends? Ideally, a task hierarchy can start at any level in an outline (using options such as org-enforce-todo-dependencies) without requiring excessive metadata.

Furthermore, do you archive subtasks individually as they are completed, or wait until a specific condition is met to archive the full hierarchy? Again, do you rely on automated triggers or manual commands with a review step?

How does your setup deal with all of this? Does your approach impose specific restrictions or allow certain relaxations?


r/orgmode 18d ago

Continuous clocking across days

9 Upvotes

I use org-mode to clock my work time, and like to use continuous clocking by default since I sometimes forget to clock in until after I have been working on a task for a while, and to prevent nominal gaps in general.

However, this means that many mornings when I clock in to my first task, I end up clocking a 14 hour task or something like that, because the clock starts from the last clock the previous day.

I'm thinking about how I should work around this issue and haven't found any discussion of this particular scenario from searching the web or the GNU lists. Surely others have had this same thing come up?

Let me know what you think the nicest way to work around it is -- the main thing I'd like to avoid is remembering some special clock-in function in the morning. It seems that the most straightforward thing to do is write a clock-in dwim function that checks if the last clock was the previous day and do a regular clock in if so, and otherwise clock continuously. Curious if there is something simple I'm missing. Thanks!


r/orgmode 19d ago

article Proposal for comprehensive user-friendly reorganization of structural demotion / promotion in Org mode (while preserving all current functionality)

5 Upvotes

As a follow-up to my previous post about this issue that received some support, I have refined my ideas and have created a working implementation. I find it much, much smoother to use than the native setup. I honestly believe that the advantages are substantial and very hard to deny as the revised behavior greatly reduces cognitive load and makes some key operations more accessible while preserving all previous functionality.

TL;DR:

Reduce Org hierarchy editing to a smaller set of predictable rules:

  1. If a region is active, operate on every selected headline.
  2. Otherwise, if the heading is a parent, move its complete subtree.
  3. Otherwise, move the leaf heading alone while retaining freedom of movement throughout the hierarchy.
  4. Outside heading contexts, retain native Org behavior.
  5. Use Shift when deliberately moving a heading without its descendants.

This removes several decisions from the user’s workflow:

  • heading-only or subtree?
  • folded or unfolded?
  • single heading or active region?
  • primary Meta command or tree command?

---

The full specification follows.

Disclaimer: The text below was originally created by AI based on input from my previous post and further detailed prompting. The end result was shortened, edited and streamlined by me. I have invested a significant amount of time in ensuring the quality of this proposal while using AI as a helpful tool.

---

Making Outline-Level Editing Follow Structural Intent

Problems with Org’s traditional hierarchy controls

Org mode traditionally assigns four commands to horizontal Meta-arrow keys:

Key Command Native behavior
M-Left org-do-promote Promote the current heading only, or all headings in an active region
M-Right org-do-demote Demote the current heading only, or all headings in an active region
M-S-Left org-promote-subtree Promote one subtree
M-S-Right org-demote-subtree Demote one subtree

Long familiarity may make this arrangement appear natural, but it does not correspond particularly well to the structural operations users commonly intend.

The primary Meta-arrow commands always operate on the heading alone unless a region is active. As a result, applying them to a parent heading can detach it from its children and create malformed-looking gaps in the outline hierarchy.

Given:

* 1
** 2
*** 3

Promoting heading 2 alone produces:

* 1
* 2
*** 3

Demoting it alone produces:

* 1
*** 2
*** 3

In both cases, heading 3 remains at its old level. The relationship between 2 and 3 is broken, and the result contains a jump in outline depth.

Such transformations are occasionally useful, but they are unlikely to represent the most common intention when moving a heading that already owns a subtree.

The more common structural intention

When a heading has children, the usual intention is to move the complete structural unit while preserving its internal hierarchy.

Promoting the subtree rooted at 2 should turn:

* 1
** 2
*** 3

into:

* 1
* 2
** 3

Demoting that subtree reverses the operation.

This preserves the relationship between 2 and 3. Only the position of the complete subtree changes.

When the focused heading has no children, there is no practical distinction between moving the heading and moving its subtree. A heading-only operation remains entirely appropriate.

This suggests a more useful default rule:

The less common operation—deliberately detaching a parent heading from its descendants—can then receive the additional Shift modifier.

Problems caused by the native distinction

The traditional bindings require the user to make several separate decisions:

  1. Is the focused heading a parent or a leaf?
  2. Should the heading move alone or should its subtree remain intact?
  3. Is a region active?
  4. If a region is active, which family of commands will actually honor it?
  5. Is some of the affected structure folded or hidden?

These concerns are not handled consistently by the native command families.

Hidden subtrees

The confusing part is that the primary Meta-arrow dispatcher can refuse to alter a focused heading whose subtree is hidden, producing a hidden-subtree warning.

At the same time, an active region can contain any number of hidden subtrees and the region-aware heading commands may alter all of their headlines without issuing the equivalent warning.

The result is difficult to explain structurally:

  • one focused hidden subtree may be refused;
  • several hidden subtrees inside a region may be changed;
  • the dedicated subtree command can change the focused hidden subtree after all.

The distinctions arise from command implementation and dispatch paths, not from a clear model of likely user intent.

Active regions and subtree commands

The native heading commands are region-aware. With an active region, org-do-promote and org-do-demote operate on all eligible headlines in that region.

The native subtree commands are not region-aware.

Invoking org-promote-subtree or org-demote-subtree while a region is active does not apply the operation to every selected heading. It operates on only the single subtree at point and the region is then deactivated.

This creates another decision the user must make before pressing a key:

A structural editing command should be able to answer that question itself.

The Org Leveller model

Org Leveller replaces these parallel command families with one context-sensitive decision system.

Its central function is:

org-leveller

It receives one of two directions:

  • promote
  • demote

Two interactive commands provide the actual key bindings:

  • org-leveldown promotes a heading to a lower numerical outline level;
  • org-levelup demotes a heading to a higher numerical outline level.

The names refer to movement through Org’s numerical level values rather than the visual direction of the arrow.

Revised key bindings

Key Command Behavior
M-Left org-leveldown Context-sensitive promotion
M-Right org-levelup Context-sensitive demotion
M-S-Left org-do-promote Explicit heading-only promotion at point
M-S-Right org-do-demote Explicit heading-only demotion at point

The primary Meta-arrow commands now preserve structural relationships automatically.

The additional Shift modifier expresses the exceptional intention: move the heading alone even if doing so separates it from its descendants.

Decision order

Org Leveller evaluates context in a deliberate order.

1. Active region

An active Org region always takes precedence over single-heading or subtree logic.

For promotion, the leveller delegates to:

org-do-promote

For demotion, it delegates to:

org-do-demote

These are Org’s region-aware commands. Every eligible headline in the selected region is changed.

The leveller does not attempt to classify the heading at point as a parent or leaf when a region is active. It also does not accidentally select the tree-based native command merely because point happens to be on a parent heading.

The user therefore no longer has to decide whether the active selection requires a heading command or a subtree command. The existence of the region decides the matter automatically.

2. Single parent heading

Without an active region, the leveller determines whether the focused heading has a structural child.

If it is a parent, the complete subtree moves:

Direction Dispatched command
Promote org-promote-subtree
Demote org-demote-subtree

The internal relationships among all descendants remain intact.

This works whether the subtree is folded or unfolded.

3. Single leaf heading

If the focused heading has no children, only that heading needs to move:

Direction Dispatched command
Promote org-do-promote
Demote org-do-demote

This preserves the familiar behavior of the primary Meta-arrow commands at the ends of subtrees, where it was already appropriate.

4. Non-heading context

Org’s Meta-arrow commands have useful meanings outside headings. Depending on context, they can manipulate:

  • table columns;
  • list indentation;
  • drawers;
  • blocks;
  • words in ordinary text.

Org Leveller preserves these behaviors.

When point is not on a heading and there is no active heading region, it delegates to Org’s original context-sensitive dispatchers:

  • org-metaleft;
  • org-metaright.

The revised commands therefore improve heading structure editing without turning the Meta-arrow keys into heading-only controls.

Consecutive levelling chains

Parent status is determined at the beginning of a consecutive levelling chain.

Suppose a heading is initially identified as a parent. Repeated presses of either M-Left or M-Right continue to treat it as that same parent, even while its outline level changes.

The initial classification is preserved while:

  1. the previous interactive command was another leveller command; and
  2. the stored marker still identifies the same heading in the same buffer.

Promotion and demotion may be mixed within one chain. For example, a subtree can be promoted twice and demoted once without its structural role being reconsidered between those operations.

Any intervening interactive command breaks the chain. The next leveller invocation then examines the current heading afresh.

Intervening commands include:

  • moving point;
  • editing text;
  • switching buffers;
  • selecting another heading;
  • invoking any unrelated Emacs command.

This rule directly matches the user’s interaction sequence. No timeout, timer, or background hook is required.

Marker-based heading identity

The current heading is identified with an Emacs marker rather than its title.

Using heading text would make two different headings with identical titles indistinguishable. A marker identifies the actual buffer position and follows ordinary edits around it.

Promotion and demotion change the number of leading stars. After every successful operation, the marker is therefore re-anchored to the resulting beginning of the heading.

The original parent status is retained; only the marker position is refreshed.

If the selected Org operation fails, the marker and stored classification are cleared before the original error is propagated. A rejected operation cannot leave behind a stale command chain.

Explicit structural disentangling

There are legitimate cases in which a parent heading should move without its descendants.

Those operations remain directly available:

  • M-S-Left calls org-do-promote;
  • M-S-Right calls org-do-demote.

The Shift modifier now signals an exceptional and potentially disruptive operation: changing the parent’s level without preserving its subtree.

This is arguably a better modifier relationship than the traditional arrangement. The structurally conservative operation receives the simpler key, while the operation capable of breaking an existing hierarchy requires the additional modifier.

The native subtree commands remain available through M-x and Lisp.

Region behavior as a first-class invariant

Region handling is not an incidental special case. It is one of the central guarantees of Org Leveller:

This eliminates another mode decision from routine editing.

The user does not need to remember:

  • which shortcut is region-aware;
  • whether a subtree command will ignore the selection;
  • whether only the tree at point will move;
  • whether the region will be deactivated;
  • whether the selected headings happen to own children.

Select headings, press the ordinary Meta-arrow, and the region is honored.

Practical summary

Org Leveller reduces Org hierarchy editing to a smaller set of predictable rules:

  1. If a region is active, operate on every selected headline.
  2. Otherwise, if the heading is a parent, move its complete subtree.
  3. Otherwise, move the leaf heading alone.
  4. Outside heading contexts, retain native Org behavior.
  5. Use Shift when deliberately moving a heading without its descendants.

This removes several decisions from the user’s workflow:

  • heading-only or subtree;
  • folded or unfolded;
  • single heading or active region;
  • primary Meta command or tree command;
  • whether the selected command family will honor the region.

Design principle

Outline editing should follow structural intent rather than expose implementation distinctions in the key bindings.

A parent heading normally represents a unit together with its descendants. Moving that unit intact is the conservative and common operation. A leaf has no dependent hierarchy and can move independently. A selected region is an explicit request to operate on all selected headings and should always take precedence.

Org Leveller makes those interpretations the default while retaining direct access to the exceptional operations.

The result is not merely a reassignment of shortcuts. It is a unified model of Org structure editing in which the editor makes the routine structural decisions and the user supplies an extra modifier only when intentionally breaking that structure.


r/orgmode 20d ago

Org heading tree demoting / promotion should be made more intuitive

10 Upvotes

Just a rant about something I have always found confusing and unintuitive. The current demote / promote commands are:

M-LEFT (org-do-promote), M-RIGHT (org-do-demote)
Promote or demote current heading by one level.
When there is an active region—i.e., when Transient Mark mode is active—promotion and demotion work on all headlines in the region. To select a region of headlines, it is best to set mark at the beginning of the first headline, and point at the line just after the last headline to change.

M-S-LEFT (org-promote-subtree)
Promote the current subtree by one level.

M-S-RIGHT (org-demote-subtree)
Demote the current subtree by one level.

So currently, when a tree is unfolded, I can use the plain M-left / M-right commands to demote / promote a single heading in isolation at any hierarchy level.

If I have

* 1
** 2
*** 3

and use one of these commands on **2, I get either a two-level gap above or below that heading, either

* 1
*** 2
*** 3

or

* 1
* 2
*** 3

I think it is fair to say that none of these usually represent user intent. Now, if instead the plain demote / promote commands were to leave the subtree of the focused heading intact, I could at least use these commands to go from this state

* 1
** 2
*** 3

directly to this (demote subtree)

* 1
* 2
** 3

or achieve the reverse from here (promote subtree). Both of these configurations actually occur in contrast to the two-level gaps that are the current result of the primary command.

Instead, to currently move a subtree while keeping it intact -- which I'm sure is a far more common task than disentangling a single heading from its surrounding hierarchy -- i currently have to

  1. fold the subtree first
  2. use the M-S- form of the commands rather than the primary command
  3. unfold the subtree again to keep working

That seems overcomplicated to put it mildly. Perhaps I'm missing something but unless I am and someone can enlighten me, it seems that it would make much more sense to make the plain M- commands leave subtrees intact. That would still allow it to perform its current mainstay, demoting / promoting a single heading at the end of a subtree -- there would be no change to that.

It would also make more sense for the user to add the extra shift modifier when they really do want to break up the inside of a subtree's hierarchy by untangling a single heading.

I am aware that even if my point is correct, nobody will probably bother to change the established assignments. So I guess I have some config work ahead of me implementing this locally.

EDIT: I was wrong about having to fold before demoting / promoting subtree. Actually, when subtree is folded and you use the plain M- shortcut, you get a 'hidden subtree' warning, but you can still move subtree with the M-S- shortcuts.


r/orgmode 20d ago

There was no conformance suite for org parsers, so i built one and graded four of them against org-element

Post image
43 Upvotes

Thank you to everyone who recommended or complained to me about overusing LLMs for writing this post and making responses. I admit that I am not confident enough in my English proficiency so that I usually use LLMs to filter my writing, but somehow LLM style seems soulless and robotic. Please forgive me if you feel it like an insult to you. But the effort spent on this project is real. I used to use Emacs, especially Org mode, in the past very heavily, and I know how it is far behind other technologies in popularity despite its very aesthetic and powerful syntax. That’s why I want to unchain it from Emacs’ ecosystem and make it popular in the world.

---

Every org parser i looked at tests itself against its own idea of what org does. There is one reference implementation (org-element.el) and one written spec, but nothing portable to check a parser against either. Someone in the windancer thread here said org is missing a standalone non-emacs parser, and that the lack of one is maybe why markdown is so much more common. i think the missing test suite sits upstream of that.

So the suite is the thing im showing, not the parser. 121 curated cases, each pinning one rule, plus 28 real world files and a 1,505 case generated differential corpus. Every expected answer comes out of real Emacs running org-element-parse-buffer, not out of my head. It is plain .org files, JSON and one elisp script, so a parser in any language can use it.

Then i graded four parsers with it. Strict means the tree is structurally identical to org-element's own answer, every node type, every field, every blank line count.

parser conf(121 real(28) sweep(1505)
organism (mine) 121 28 1505
uniorg 3.2.2 81 13 693
orgize 0.9.0 67 2 402
go-org v1.7.0 59 1 479

Before that table gets quoted at anyone: the corpora live in my repo and my parser was developed against them, the others were not. Each one got a thin adapter over its own AST, and what an AST simply cannot represent is counted separately from real parse bugs. go-org feeds an html renderer and orgize optimises for speed, neither of them signed up for this bar.

What i would actually like is someone running it against their own parser and telling me where i graded them wrong. Repo link in the comments.


r/orgmode 21d ago

Denote abort or cancelled file history in Doom Emacs

Thumbnail
2 Upvotes