emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Ihor Radchenko <yantar92@posteo.net>
To: Tom Alexander <tom@fizz.buzz>
Cc: emacs-orgmode@gnu.org
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	[thread overview]
Message-ID: <8734y5d2gs.fsf@localhost> (raw)
In-Reply-To: <2c9a6cbd-21c0-45bf-8fbb-4f7eccac4ae7@app.fastmail.com>

[-- Attachment #1: Type: text/plain, Size: 713 bytes --]

"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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-lisp-org.el-org-mode-Force-tab-width-to-be-8.patch --]
[-- Type: text/x-patch, Size: 4177 bytes --]

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: 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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-org-syntax.org-Indentation-Clarify-that-tabs-occupy-.patch --]
[-- Type: text/x-patch, Size: 1248 bytes --]

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


[-- Attachment #4: Type: text/plain, Size: 224 bytes --]


-- 
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	other threads:[~2023-10-20 10:14 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-29 18:16 COUNTER-SET for alphabetical ordered lists ignored for utf-8 exporter Tom Alexander
2023-10-07 10:29 ` Ihor Radchenko
2023-10-11 14:28   ` Tom Alexander
2023-10-20 10:15     ` Ihor Radchenko [this message]
2023-12-05 13:13       ` [PATCH] [DISCUSSION] Force `tab-width' to be 8 in Org mode (was: COUNTER-SET for alphabetical ordered lists ignored for utf-8 exporter) Ihor Radchenko
2023-10-20 10:18     ` COUNTER-SET for alphabetical ordered lists ignored for utf-8 exporter Ihor Radchenko
2024-04-05 17:06   ` Stacey Marshall
2024-04-06 12:02     ` Ihor Radchenko
2024-04-06 12:25       ` Stacey Marshall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8734y5d2gs.fsf@localhost \
    --to=yantar92@posteo.net \
    --cc=emacs-orgmode@gnu.org \
    --cc=tom@fizz.buzz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).