From 423cf9aef588ed93cbc06d6033feaf6bf1a91dfc Mon Sep 17 00:00:00 2001 Message-ID: <423cf9aef588ed93cbc06d6033feaf6bf1a91dfc.1697796750.git.yantar92@posteo.net> From: Ihor Radchenko 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