Skip to content

About

Formatting org-mode buffer to reduce merge conflicts by useless whitespace edits

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

orgzly-formatter

https://github.com/stfl/orgzly-formatter.el/actions/workflows/ci.yml/badge.svg

When using Orgzly Revived with the git repository features on Android and git-sync on other machines, format changes by Orgzly to the underlying org file cause frequent merge conflicts.

Enforces blank-line and whitespace conventions that keep org files byte-for-byte identical between Emacs and Orgzly Revived (the Android org client), eliminating spurious git diffs produced by Orgzly’s own auto-formatter.

The problem

Orgzly silently reformats org files on every edit. Even for entries not changed by Orgzly:

  • Adds a blank line after entries that have content
  • Adds a blank line after entries that have only a properties drawer
  • Puts exactly one blank line between an entry’s heading (or its planning line) and the body text under it
  • Removes extra trailing blank lines at end-of-file

Each of these appears as a one-line diff in git, causing merge conflicts when the same file is edited in both Emacs and Orgzly.

The solution

orgzly-formatter runs as a before-save-hook and pre-emptively applies the same rules Orgzly would, so the files Emacs writes are already in Orgzly’s preferred format. Orgzly then has nothing to change.

Rules

RuleDescription
R1Exactly one blank line before each heading (except at buffer start). A heading immediately preceded by another empty heading gets no blank line.
R2One blank line between a drawer :END: and the body text that follows it. A drawer that ends a section (no body follows) is left unchanged, and so is a drawer before the first heading, which Orgzly keeps as written. After the property drawer of an entry’s head, R5 sets the gap.
R3Exactly one blank line at the end of every entry that has content (planning, drawer, or body). Heading-only entries get no trailing blank.
R4Planning keywords (CLOSED / DEADLINE / SCHEDULED) on the line after a heading are rewritten in Orgzly’s canonical order — CLOSED DEADLINE SCHEDULED, single-space separated. Existing indentation is preserved.
R5Exactly one blank line between an entry’s head (its heading line, any planning line under it, which needs a timestamp, and a :PROPERTIES: drawer under those) and the body text that follows; surplus blank lines are removed. Orgzly writes a drawer, a CLOCK: line or a log note (- State …, - Note taken on …) directly under the head, so the blank lines before one are removed. Matching is case-sensitive, as in Orgzly. An entry whose planning line Org reads but Orgzly does not (a diary sexp such as <%%(diary-float t 4 2)>) is left alone, so Emacs keeps it scheduled.
WSTrailing whitespace stripped from every line, including a carriage return before the newline. Exception: =* NEXT = (keyword-only heading with a single trailing space) is preserved — org needs it.
EOFBuffer ends with exactly one blank line.

The formatter is idempotent: running it on an already-correct buffer produces no changes.

Formatting in Orgzly can be changed via Settings -> Sync -> Org file format. This package considers the default settings of:

Separate note with an empty line
Multiline notes only
Separate header and content
true

Requirements

  • Emacs 27.1+
  • Org 9.7+

Installation

straight.el + use-package

(use-package orgzly-formatter
  :straight (:host github :repo "stfl/orgzly-formatter.el")
  :hook (org-mode . orgzly-formatter-mode))

Doom Emacs

In packages.el:

(package! orgzly-formatter
  :recipe (:host github :repo "stfl/orgzly-formatter.el"))

In config.el:

(use-package orgzly-formatter
  :hook (org-mode . orgzly-formatter-mode))

Then run doom sync and restart Emacs.

Configuration

Enable globally (recommended)

;; Activates orgzly-formatter-mode in every org-mode buffer via hook.
(orgzly-formatter-global-setup)

Run once without the mode

M-x orgzly-formatter-buffer

Disable conflicting ws-butler mode in org-mode buffers

(with-eval-after-load 'ws-butler
  (add-to-list 'ws-butler-global-exempt-modes 'org-mode))

About

Formatting org-mode buffer to reduce merge conflicts by useless whitespace edits

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages