emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] [DISCUSSION] Force `tab-width' to be 8 in Org mode (was: COUNTER


From: Ihor Radchenko
Subject: [PATCH] [DISCUSSION] Force `tab-width' to be 8 in Org mode (was: COUNTER-SET for alphabetical ordered lists ignored for utf-8 exporter)
Date: Fri, 20 Oct 2023 10:15:31 +0000

"Tom Alexander" <tom@fizz.buzz> writes:

> Thanks!
>
>> We aim to reduce config-dependent Org syntax in the long term.
>
> Thats wonderful news! Sometimes this stuff can really surprise you. For 
> example, the structure of the document created by running `echo "1. foo\n 
> 1.bar\n        1.baz\n\t1.lorem"` changes based on the user's **tab-width**!!
> ...
> Absolute madness! I always considered tab-width to be a personal aesthetic 
> choice and not something that would functionally change how documents other 
> people wrote will be parsed.

I agree.
See the attached tentative patches for Org mode and org-syntax.

This is a breaking change, so I encourage people who might be affected
reply if they have objections.

>From 423cf9aef588ed93cbc06d6033feaf6bf1a91dfc Mon Sep 17 00:00:00 2001
Message-ID: 
<423cf9aef588ed93cbc06d6033feaf6bf1a91dfc.1697796750.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Fri, 20 Oct 2023 13:10:30 +0300
Subject: [PATCH] * lisp/org.el (org-mode): Force `tab-width' to be 8

* lisp/org-macs.el (org-current-text-column): Assert `tab-width' to be
8 to ensure consistency of the parser across user configurations.
* etc/ORG-NEWS (~tab-width~ value is now assumed to be 8): Document
the breaking change.

This breaking change is made to standardize Org mode format for list
items.  With variable `tab-width', indentation in lists may depend on
user settings leading to inconsistent Org documents when open by
different users.

Link: 
2c9a6cbd-21c0-45bf-8fbb-4f7eccac4ae7@app.fastmail.com">https://orgmode.org/list/2c9a6cbd-21c0-45bf-8fbb-4f7eccac4ae7@app.fastmail.com
---
 etc/ORG-NEWS     | 34 ++++++++++++++++++++++++++++++++++
 lisp/org-macs.el | 13 ++++++++++---
 lisp/org.el      |  3 +++
 3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 78b75b578..ea8ebd3af 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -13,6 +13,40 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
 
 * Version 9.7 (not released yet)
 ** Important announcements and breaking changes
+*** ~tab-width~ value is now assumed to be 8
+
+Org mode now assumes tab width to be 8 characters, when calculating
+list and other indentation.  ~tab-width~ is also set to 8 when Org
+major mode is loaded.
+
+This is done to improve consistency of the markup for lists, where
+indentation affects list items.
+
+Users with non-default values of ~tab-width~ should avoid overriding
+the value of 8 set by Org mode.  If the custom ~tab-width~ value is
+_smaller_ than 8, the existing Org documents can be converted to the
+new standard tab width using the following helper command:
+
+#+begin_src emacs-lisp
+(defun org-compat-adjust-tab-width-in-buffer (old-width)
+  "Adjust visual indentation from `tab-width' equal OLD-WIDTH to 8."
+  (interactive "nOld `tab-width': ")
+  (cl-assert (derived-mode-p 'org-mode))
+  (unless (= old-width 8)
+    (org-with-wide-buffer
+     (goto-char (point-min))
+     (let (bound
+          (repl (if (< old-width 8)
+                    (make-string old-width ?\s)
+                   (concat "\t" (make-string (- old-width 8) ?\s)))))
+       (while (re-search-forward "^ *\t" nil t)
+        (skip-chars-forward " \t")
+        (setq bound (point-marker))
+        (forward-line 0)
+        (while (search-forward "\t" bound t)
+          (replace-match repl)))))))
+#+end_src
+
 *** New export option ~org-export-expand-links~
 
 The new option makes Org expand environment variables in link and INCLUDE 
paths.
diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index fd0f508c5..1fd7dd704 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -1148,9 +1148,16 @@ (defun org-string-width (string &optional pixels)
             (/ pixel-width symbol-width)))))))
 
 (defmacro org-current-text-column ()
-  "Like `current-column' but ignore display properties."
-  `(string-width (buffer-substring-no-properties
-                  (line-beginning-position) (point))))
+  "Like `current-column' but ignore display properties.
+Throw an error when `tab-width' is not 8.
+
+This function forces `tab-width' value because it is used as a part of
+the parser, to ensure parser consistency when calculating list
+indentation."
+  `(progn
+     (cl-assert (= 8 tab-width))
+     (string-width (buffer-substring-no-properties
+                    (line-beginning-position) (point)))))
 
 (defun org-not-nil (v)
   "If V not nil, and also not the string \"nil\", then return V.
diff --git a/lisp/org.el b/lisp/org.el
index bda64bb6c..671dfbe38 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -4846,6 +4846,9 @@ (define-derived-mode org-mode outline-mode "Org"
 
 \\{org-mode-map}"
   (setq-local org-mode-loading t)
+  ;; Force tab width - indentation is significant in lists, so we need
+  ;; to make sure that it is consistent across configurations.
+  (setq-local tab-width 8)
   (org-load-modules-maybe)
   (when org-agenda-file-menu-enabled
     (org-install-agenda-files-menu))
-- 
2.42.0

>From 1ce9ef2f8e475bcb8b9be7367bb30aa0983da6ea Mon Sep 17 00:00:00 2001
Message-ID: 
<1ce9ef2f8e475bcb8b9be7367bb30aa0983da6ea.1697637104.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Wed, 18 Oct 2023 16:51:26 +0300
Subject: [PATCH] * org-syntax.org (Indentation): Clarify that tabs occupy 8
 characters

---
 org-syntax.org | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/org-syntax.org b/org-syntax.org
index 9e9b0420..3089ddcf 100644
--- a/org-syntax.org
+++ b/org-syntax.org
@@ -240,7 +240,9 @@ ** Indentation
 Indentation consists of a series of space and tab characters at the
 beginning of a line.  Most elements can be indentated, with the
 exception of [[#Headings][headings]], [[#Inlinetasks][inlinetasks]], 
[[#Footnote_Definitions][footnote definitions]], and [[#Diary_Sexp][diary
-sexps]].  Indentation is only syntactically meaningful in plain lists.
+sexps]].  Indentation is only syntactically meaningful in plain lists,
+where indentation is calculated assuming that space characters occupy
+a single character and tab characters occupy 8 characters.
 
 The common indentation of all the lines within an element is
 discarded.  This also applies to single-line elements.
-- 
2.42.0

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]