emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "Sébastien Miquel" <sebastien.miquel@posteo.eu>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: wolf <wolf@wolfsden.cz>, emacs-orgmode@gnu.org
Subject: Re: [BUG] Source block indentation does not work properly for yaml-mode [9.6.6 ( @ /home/user/.emacs.d/elpa/org-9.6.6/)]
Date: Thu, 29 Jun 2023 15:54:59 +0000	[thread overview]
Message-ID: <1d145455-2047-2b7a-8222-8eadc2529c8c@posteo.eu> (raw)
In-Reply-To: <87o7l0vt5z.fsf@localhost>

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

Hi Ihor,

Thank you for the feedback.

Ihor Radchenko writes:
>> +      ;; Apply WRITE-BACK function on edit buffer contents.
>> +      (goto-char (point-min))
>> +      (when (functionp write-back) (save-excursion (funcall write-back)))
>>         (set-marker marker nil))))
> `save-excursion' is no longer necessary here.

Done.

>>   (defun org-src--edit-element
>> @@ -1150,7 +1149,14 @@ Throw an error when not at such a table."
>>          (lambda ()
>>   	 ;; Blank lines break things, replace with a single newline.
>>   	 (while (re-search-forward "\n[ \t]*\n" nil t) (replace-match "\n"))
>> -	 ;; If within a table a newline would disrupt the structure,
>> +         ;; Trim contents.
> It would be nice to have a bit more context about the purpose in the
> comment here.

I was confused. We need only trim the beginning of the result, for the
indentation added by `org-src--contents-for-write-back'. I've added an
explanation.

>>   ...
>> -	  (skip-chars-forward " \t")
>> -          (when (or (not (eolp))                               ; not a blank line
>> -                    (and (eq (point) (marker-position marker)) ; current line
>> +          (when (or (not (eolp)) ; not an empty line
>> +                    ;; If the current line is empty, we may
>> +                    ;; want to indent it.
>> +                    (and (eq (point) (marker-position marker))
>>                            preserve-blank-line))
> Do we still need this dance with special case for current line?

Yes. This is fragile, but what it does is, if the line from which the
original edit was called was blank and not empty, and the line from
which the edit is ended is empty, we assume these two lines are the
same, and we add the common block indentation to this empty line.
This, and the pre-indentation in =org-indent-line=, make `TAB` work
to indent an empty line.

The logic in =org-edit-element= can now be simplified though, see the
third patch attached.

>> +    ;; Display tab indentation characters preceded by spaces as spaces
>> +    (unless org-src-preserve-indentation
> unless? Don't we rather want to preserve the original indentation
> alignment when `org-src-preserve-indentation' is t?
>> +      (save-excursion
>> +        (goto-char start)
>> +        (while (re-search-forward "^[ ]+\\([\t]+\\)" end t)
> Why just tabs at indentation? It would make sense to preserve width of
> all the tabs.
>> +          (let* ((b (match-beginning 1))
>> +                 (e (match-end 1))
>> +                 (s (make-string (* (- e b) native-tab-width) ? )))
>> +            (add-text-properties b e `(display ,s))))))
> Will the actual tab width be always equal to native-tab-width? What
> about tab stops? May it be more reliable to use different of column
> numbers in the src mode buffer after/before the tab?

I was trying to be conservative. When =org-src-preserve-indentation=
is t, I guess we can do the same, for consistency.

As you say, the tabs at the beginning of indentation are the only ones
we can be somewhat sure of the width, if we assume the native
indentation was done sanely (using tabs then spaces). I'm inclined to
only deal with those.

To get the true tab widths, we'd need to get the columns numbers in
yet a third different buffer, with the common indentation removed. I
don't think that's worth it.

Anyway, what I wrote doesn't deal correctly with the case where the
org indentation may use tabs. I've updated the patch: I use the value
of what should be the org indentation, and only change the display of
the following consecutive tabs.

>> @@ -318,19 +318,21 @@ This is a tab:\t.
>>                 argument2))
>>     #+END_SRC"
>>         (setq-local indent-tabs-mode t)
>> -      (let ((org-edit-src-content-indentation 2)
>> +      (let ((tab-width 8)
>> +            (org-edit-src-content-indentation 2)
> Why is setting tab-width necessary? 8 is the default value.

Removed, though I have left an instance of =(setq-local tab-width 8)=,
for clarity.

>>     #+BEGIN_SRC emacs-lisp<point>
>> -    (progn\n      (function argument1\n\t\targument2))
>> +    (progn\n      (function argument1\n    \targument2))
> I think it would be a bit more readable to convert this string into
> actual multi-line, where the alignment is visible when reading the test
> source.

I've left it this way. I think the tests using tab characters are
often written this way, so as to be understandable without whitespace
mode.

-- 
Sébastien Miquel

[-- Attachment #2: 0001-org-src-contents-for-write-back-simplify-the-case-of.patch --]
[-- Type: text/x-patch, Size: 3037 bytes --]

From d024fe96ad889097d025a87dae3316acc44299f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= <sebastien.miquel@posteo.eu>
Date: Sun, 25 Jun 2023 13:38:21 +0200
Subject: [PATCH] org-src--contents-for-write-back: simplify the case of LaTeX
 fragments

* lisp/org-src.el (org-src--contents-for-write-back): Extract special
case logic for LaTeX fragments.
(org-edit-latex-fragment): Trim the contents to be inserted in the
original buffer.
---
 lisp/org-src.el | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lisp/org-src.el b/lisp/org-src.el
index f15ba8e99..121e59241 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -466,7 +466,6 @@ Assume point is in the corresponding edit buffer."
 		  org-src--content-indentation
 		0))))
 	(use-tabs? (and (> org-src--tab-width 0) t))
-        (preserve-fl (eq org-src--source-type 'latex-fragment))
 	(source-tab-width org-src--tab-width)
 	(contents (org-with-wide-buffer
                    (let ((eol (line-end-position)))
@@ -479,16 +478,13 @@ Assume point is in the corresponding edit buffer."
       ;; Reproduce indentation parameters from source buffer.
       (setq indent-tabs-mode use-tabs?)
       (when (> source-tab-width 0) (setq tab-width source-tab-width))
-      ;; Apply WRITE-BACK function on edit buffer contents.
       (insert (org-no-properties (car contents)))
       (setq marker (point-marker))
       (insert (org-no-properties (car (cdr contents))))
       (goto-char (point-min))
-      (when (functionp write-back) (save-excursion (funcall write-back)))
       ;; Add INDENTATION-OFFSET to every line in buffer,
       ;; unless indentation is meant to be preserved.
       (when (> indentation-offset 0)
-	(when preserve-fl (forward-line))
         (while (not (eobp))
 	  (skip-chars-forward " \t")
           (when (or (not (eolp))                               ; not a blank line
@@ -498,6 +494,9 @@ Assume point is in the corresponding edit buffer."
 	      (delete-region (line-beginning-position) (point))
 	      (indent-to (+ i indentation-offset))))
 	  (forward-line)))
+      ;; Apply WRITE-BACK function on edit buffer contents.
+      (goto-char (point-min))
+      (when (functionp write-back) (funcall write-back))
       (set-marker marker nil))))
 
 (defun org-src--edit-element
@@ -1150,7 +1149,12 @@ Throw an error when not at such a table."
        (lambda ()
 	 ;; Blank lines break things, replace with a single newline.
 	 (while (re-search-forward "\n[ \t]*\n" nil t) (replace-match "\n"))
-	 ;; If within a table a newline would disrupt the structure,
+         ;; Trim contents: `org-src--contents-for-write-back' may have
+         ;; added indentation at the beginning, which we remove.
+	 (goto-char (point-min))
+         (skip-chars-forward " \t")
+	 (delete-region (point-min) (point))
+         ;; If within a table a newline would disrupt the structure,
 	 ;; so remove newlines.
 	 (goto-char (point-min))
 	 (when (org-element-lineage context '(table-cell))
-- 
2.41.0


[-- Attachment #3: 0001-org-src.el-Use-native-value-of-indent-tabs-mode-for-.patch --]
[-- Type: text/x-patch, Size: 9141 bytes --]

From f6ed74b536723e2c888b51f8d0ecc84e104411fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= <sebastien.miquel@posteo.eu>
Date: Tue, 27 Jun 2023 09:23:01 +0200
Subject: [PATCH] org-src.el: Use native value of `indent-tabs-mode' for
 indentation

* lisp/org-macs.el (org-do-remove-indentation): Preserve
indentation (spaces vs tabs) past the common indentation to remove.
* lisp/org-src.el (org-src--contents-for-write-back): Preserve the
native indentation (spaces vs tabs).  If necessary, add a common org
indentation to the block according to org's `indent-tabs-mode'.
(org-src-font-lock-fontify-block): In case of mixed indentation,
display the tab characters with a fixed width, according to the native
tab width value.
* testing/lisp/test-org-src.el (test-org-src/indented-blocks): Update
tests.  Indentation no longer obeys `indent-tabs-mode' from the org
buffer, but is separated in two parts.
---
 lisp/org-macs.el             |  4 +-
 lisp/org-src.el              | 41 ++++++++++++++------
 testing/lisp/test-org-src.el | 75 ++++++++++++++++++++++--------------
 3 files changed, 79 insertions(+), 41 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 51dbfe118..f42e6b14b 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -485,7 +485,9 @@ line.  Return nil if it fails."
 	  (let ((ind (progn (skip-chars-forward " \t") (current-column))))
 	    (cond ((eolp) (delete-region (line-beginning-position) (point)))
 		  ((< ind n) (throw :exit nil))
-		  (t (indent-line-to (- ind n))))
+		  (t (delete-region (line-beginning-position)
+                                    (progn (move-to-column n t)
+                                           (point)))))
 	    (forward-line)))
 	;; Signal success.
 	t))))
diff --git a/lisp/org-src.el b/lisp/org-src.el
index 121e59241..a8f076b21 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -473,11 +473,15 @@ Assume point is in the corresponding edit buffer."
                            (buffer-substring eol (point-max))))))
 	(write-back org-src--allow-write-back)
         (preserve-blank-line org-src--preserve-blank-line)
-        marker)
+        marker indent-str)
+    (setq indent-str
+          (with-temp-buffer
+            ;; Reproduce indentation parameters from org buffer.
+            (setq indent-tabs-mode use-tabs?)
+            (when (> source-tab-width 0) (setq tab-width source-tab-width))
+            (indent-to indentation-offset)
+            (buffer-string)))
     (with-current-buffer write-back-buf
-      ;; Reproduce indentation parameters from source buffer.
-      (setq indent-tabs-mode use-tabs?)
-      (when (> source-tab-width 0) (setq tab-width source-tab-width))
       (insert (org-no-properties (car contents)))
       (setq marker (point-marker))
       (insert (org-no-properties (car (cdr contents))))
@@ -486,13 +490,12 @@ Assume point is in the corresponding edit buffer."
       ;; unless indentation is meant to be preserved.
       (when (> indentation-offset 0)
         (while (not (eobp))
-	  (skip-chars-forward " \t")
-          (when (or (not (eolp))                               ; not a blank line
-                    (and (eq (point) (marker-position marker)) ; current line
+          (when (or (not (eolp)) ; not an empty line
+                    ;; If the current line is empty, we may
+                    ;; want to indent it.
+                    (and (eq (point) (marker-position marker))
                          preserve-blank-line))
-	    (let ((i (current-column)))
-	      (delete-region (line-beginning-position) (point))
-	      (indent-to (+ i indentation-offset))))
+            (insert indent-str))
 	  (forward-line)))
       ;; Apply WRITE-BACK function on edit buffer contents.
       (goto-char (point-min))
@@ -636,7 +639,7 @@ Leave point in edit buffer."
   "Fontify code block between START and END using LANG's syntax.
 This function is called by Emacs' automatic fontification, as long
 as `org-src-fontify-natively' is non-nil."
-  (let ((modified (buffer-modified-p)))
+  (let ((modified (buffer-modified-p)) native-tab-width)
     (remove-text-properties start end '(face nil))
     (let ((lang-mode (org-src-get-lang-mode lang)))
       (when (fboundp lang-mode)
@@ -650,6 +653,7 @@ as `org-src-fontify-natively' is non-nil."
 	      ;; Add string and a final space to ensure property change.
 	      (insert string " "))
 	    (unless (eq major-mode lang-mode) (funcall lang-mode))
+            (setq native-tab-width tab-width)
             (font-lock-ensure)
 	    (let ((pos (point-min)) next)
 	      (while (setq next (next-property-change pos))
@@ -707,6 +711,21 @@ as `org-src-fontify-natively' is non-nil."
       (when (or (facep src-face) (listp src-face))
         (font-lock-append-text-property start end 'face src-face))
       (font-lock-append-text-property start end 'face 'org-block))
+    ;; Display native tab indentation characters as spaces
+    (save-excursion
+      (goto-char start)
+      (let ((indent-offset
+	     (if org-src-preserve-indentation 0
+	       (+ (progn (backward-char)
+                         (org-current-text-indentation))
+	          org-edit-src-content-indentation))))
+        (while (re-search-forward "^[ ]*\t" end t)
+          (let* ((b (and (eq indent-offset (move-to-column indent-offset))
+                         (point)))
+                 (e (progn (skip-chars-forward "\t") (point)))
+                 (s (and b (make-string (* (- e b) native-tab-width) ? ))))
+            (when (and b (< b e)) (add-text-properties b e `(display ,s)))
+            (forward-char)))))
     ;; Clear abbreviated link folding.
     (org-fold-region start end nil 'org-link)
     (add-text-properties
diff --git a/testing/lisp/test-org-src.el b/testing/lisp/test-org-src.el
index 2a45ba66e..c4309ccfc 100644
--- a/testing/lisp/test-org-src.el
+++ b/testing/lisp/test-org-src.el
@@ -304,11 +304,11 @@ This is a tab:\t.
 	(insert " Foo")
 	(org-edit-src-exit)
 	(buffer-string)))))
-  ;; Global indentation obeys `indent-tabs-mode' from the original
-  ;; buffer.
-  (should
+  ;; Global indentation does not obey `indent-tabs-mode' from the
+  ;; original buffer.
+  (should-not
    (string-match-p
-    "^\t+\s*argument2"
+    "\t"
     (org-test-with-temp-text
 	"
 - Item
@@ -323,14 +323,15 @@ This is a tab:\t.
 	(org-edit-special)
 	(org-edit-src-exit)
 	(buffer-string)))))
+  ;; Tab character is preserved
   (should
    (string-match-p
-    "^\s+argument2"
+    "\targument2"
     (org-test-with-temp-text
 	"
 - Item
   #+BEGIN_SRC emacs-lisp<point>
-    (progn\n      (function argument1\n\t\targument2))
+    (progn\n      (function argument1\n    \targument2))
   #+END_SRC"
       (setq-local indent-tabs-mode nil)
       (let ((org-edit-src-content-indentation 2)
@@ -338,43 +339,59 @@ This is a tab:\t.
 	(org-edit-special)
 	(org-edit-src-exit)
 	(buffer-string)))))
-  ;; Global indentation also obeys `tab-width' from original buffer.
+  ;; Indentation does not obey `tab-width' from org buffer.
   (should
    (string-match-p
-    "^\t\\{3\\}\s\\{2\\}argument2"
+    "^  \targument2"
     (org-test-with-temp-text
 	"
-- Item
-  #+BEGIN_SRC emacs-lisp<point>
+#+BEGIN_SRC emacs-lisp
   (progn
-    (function argument1
-              argument2))
-  #+END_SRC"
+    (list argument1\n  \t<point>argument2))
+#+END_SRC"
       (setq-local indent-tabs-mode t)
       (setq-local tab-width 4)
-      (let ((org-edit-src-content-indentation 0)
+      (let ((org-edit-src-content-indentation 2)
 	    (org-src-preserve-indentation nil))
 	(org-edit-special)
+        (setq-local indent-tabs-mode t)
+        (setq-local tab-width 8)
+        (lisp-indent-line)
 	(org-edit-src-exit)
 	(buffer-string)))))
+  ;; Tab characters are displayed with `tab-width' from the native
+  ;; edit buffer.
   (should
-   (string-match-p
-    "^\t\s\\{6\\}argument2"
+   (equal
+    10
     (org-test-with-temp-text
-	"
-- Item
-  #+BEGIN_SRC emacs-lisp<point>
+     "
+#+BEGIN_SRC emacs-lisp
   (progn
-    (function argument1
-              argument2))
-  #+END_SRC"
-      (setq-local indent-tabs-mode t)
-      (setq-local tab-width 8)
-      (let ((org-edit-src-content-indentation 0)
-	    (org-src-preserve-indentation nil))
-	(org-edit-special)
-	(org-edit-src-exit)
-	(buffer-string))))))
+    (list argument1\n  \t<point>argument2))
+#+END_SRC"
+     (setq-local indent-tabs-mode t)
+     (setq-local tab-width 4)
+     (let ((org-edit-src-content-indentation 2)
+	   (org-src-preserve-indentation nil))
+       (font-lock-ensure)
+       (current-column)))))
+  ;; The initial tab characters respect org's `tab-width'.
+  (should
+   (equal
+    10
+    (org-test-with-temp-text
+     "
+#+BEGIN_SRC emacs-lisp
+\t(progn
+\t  (list argument1\n\t\t<point>argument2))
+#+END_SRC"
+     (setq-local indent-tabs-mode t)
+     (setq-local tab-width 2)
+     (let ((org-edit-src-content-indentation 2)
+	   (org-src-preserve-indentation nil))
+       (font-lock-ensure)
+       (current-column))))))
 
 (ert-deftest test-org-src/footnote-references ()
   "Test editing footnote references."
-- 
2.41.0


[-- Attachment #4: 0001-org-src.el-Rename-internal-variable-for-clarity.patch --]
[-- Type: text/x-patch, Size: 3131 bytes --]

From 71e7a746c7d39b88038060c5b035f1c9e6f35b13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= <sebastien.miquel@posteo.eu>
Date: Thu, 29 Jun 2023 14:37:09 +0200
Subject: [PATCH] org-src.el: Rename internal variable for clarity

* lisp/org-src.el (org-src--contents-for-write-back):
(org-src--edit-element): Rename `preserve-blank-line' to
`indent-current-empty-line'.  It is used to decide whether we should
indent the current empty line after a special edit.
---
 lisp/org-src.el | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/lisp/org-src.el b/lisp/org-src.el
index ac201da44..13b7f7e20 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -318,8 +318,8 @@ is 0.")
   "File name associated to Org source buffer, or nil.")
 (put 'org-src-source-file-name 'permanent-local t)
 
-(defvar-local org-src--preserve-blank-line nil)
-(put 'org-src--preserve-blank-line 'permanent-local t)
+(defvar-local org-src--indent-current-empty-line nil)
+(put 'org-src--indent-current-empty-line 'permanent-local t)
 
 (defun org-src--construct-edit-buffer-name (org-buffer-name lang)
   "Construct the buffer name for a source editing buffer.
@@ -472,7 +472,7 @@ Assume point is in the corresponding edit buffer."
                      (list (buffer-substring (point-min) eol)
                            (buffer-substring eol (point-max))))))
 	(write-back org-src--allow-write-back)
-        (preserve-blank-line org-src--preserve-blank-line)
+        (indent-current-empty-line org-src--indent-current-empty-line)
         marker indent-str)
     (setq indent-str
           (with-temp-buffer
@@ -494,7 +494,7 @@ Assume point is in the corresponding edit buffer."
                     ;; If the current line is empty, we may
                     ;; want to indent it.
                     (and (eq (point) (marker-position marker))
-                         preserve-blank-line))
+                         indent-current-empty-line))
             (insert indent-str))
 	  (forward-line)))
       ;; Apply WRITE-BACK function on edit buffer contents.
@@ -554,8 +554,6 @@ Leave point in edit buffer."
              (blank-line (save-excursion (beginning-of-line)
                                          (looking-at-p "^[[:space:]]*$")))
              (empty-line (and blank-line (looking-at-p "^$")))
-             (preserve-blank-line (or (and blank-line (not empty-line))
-                                      (and empty-line (= (+ block-ind content-ind) 0))))
 	     (preserve-ind
 	      (and (memq type '(example-block src-block))
 		   (or (org-element-property :preserve-indent datum)
@@ -605,7 +603,8 @@ Leave point in edit buffer."
 	(setq org-src--overlay overlay)
 	(setq org-src--allow-write-back write-back)
 	(setq org-src-source-file-name source-file-name)
-        (setq org-src--preserve-blank-line preserve-blank-line)
+        (setq org-src--indent-current-empty-line (and blank-line
+                                                      (not empty-line)))
 	;; Start minor mode.
 	(org-src-mode)
 	;; Clear undo information so we cannot undo back to the
-- 
2.41.0


  reply	other threads:[~2023-06-29 15:56 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-11 22:33 [BUG] Source block indentation does not work properly for yaml-mode [9.6.6 ( @ /home/user/.emacs.d/elpa/org-9.6.6/)] wolf
2023-06-14 12:16 ` Ihor Radchenko
2023-06-17 19:11   ` Sébastien Miquel
2023-06-18 11:16     ` Ihor Radchenko
2023-06-19  8:43       ` Sébastien Miquel
2023-06-19 11:05         ` Ihor Radchenko
2023-06-19 15:32           ` Sébastien Miquel
2023-06-20 10:02             ` Ihor Radchenko
2023-06-21  5:46               ` Sébastien Miquel
2023-06-25 10:46               ` Ihor Radchenko
2023-06-26 11:14               ` Sébastien Miquel
2023-06-26 11:45                 ` Sébastien Miquel
2023-06-26 11:52                 ` Ihor Radchenko
2023-06-26 12:15                   ` Sébastien Miquel
2023-06-26 12:44                     ` Ihor Radchenko
2023-06-27  8:54                       ` Sébastien Miquel
2023-06-28  9:21                         ` Ihor Radchenko
2023-06-29 15:54                           ` Sébastien Miquel [this message]
2023-06-30 11:43                             ` Ihor Radchenko
2023-06-30 20:27                               ` Sébastien Miquel
2023-07-01 11:07                                 ` Ihor Radchenko
2023-07-01 17:17                                   ` Sébastien Miquel
2023-07-03  9:58                                     ` Ihor Radchenko
2023-07-03 12:49                                       ` Sébastien Miquel
2023-07-03 13:05                                         ` Ihor Radchenko
2023-07-03 13:48                                           ` Sébastien Miquel
2023-07-04 10:41                                             ` Ihor Radchenko
2023-07-06 11:01                                               ` Sébastien Miquel
2023-07-07  9:26                                                 ` Ihor Radchenko
2023-07-07  9:54                                                   ` Ihor Radchenko
2023-07-07 13:21                                                     ` Sébastien Miquel
2023-07-08  8:44                                                       ` Ihor Radchenko
2023-07-09 11:10                                                         ` Sébastien Miquel
2023-07-10  8:22                                                           ` Ihor Radchenko
2023-07-07  9:31                                                 ` [BUG] org-list-struct-apply-struct overrides src block indentation (was: [BUG] Source block indentation does not work properly for yaml-mode [9.6.6 ( @ /home/user/.emacs.d/elpa/org-9.6.6/)]) Ihor Radchenko
2023-07-07 13:43                                                   ` Sébastien Miquel
2023-07-08  9:06                                                     ` Ihor Radchenko

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=1d145455-2047-2b7a-8222-8eadc2529c8c@posteo.eu \
    --to=sebastien.miquel@posteo.eu \
    --cc=emacs-orgmode@gnu.org \
    --cc=wolf@wolfsden.cz \
    --cc=yantar92@posteo.net \
    /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).