3

Here's some emacs-lisp code in a babel block:

#+begin_src emacs-lisp
(defun factor (number)
  (labels
      ((*factor (divisor number)
        (if (> (* divisor divisor) number)
            (list number)
          (if (= (mod number divisor) 0)
              (cons divisor (*factor divisor (/ number divisor)))
            (*factor (+ divisor 1) number)))))
    (*factor 2 number)))
#+end_src

So in the org buffer I get a parentheses matching problem, i.e., that very last ) at the bottom is flagged as one too many. It flashes red and check-parens flags it as well. Trouble is, this is not an error, i.e., the same code in scratch is perfectly paren-matched, likewise when I bring it up in the Org Source C-c ' window. BTW, this code compiles and runs giving good output. Any ideas what org-mode is doing here? I've got (show-paren-mode 1). When I turn it off, obviously, no problem because no highlighting matching parens.

  • can't replicate.... more config detalis? – manandearth Apr 29 at 16:05
  • I don't think this block is the problem. It's evidence of some other syntax problem in your org file. I'd suggest identifying what section of your org file provokes this error. Do this by removing parts of your org file until this matching problem does not occur and adding back what you removed one by one until the error returns. – Aquaactress Apr 29 at 16:29
  • I've got this problem in a totally naked file, i.e., just the code block, no headers, saved with an .org suffix. I'm on Emacs 26.2 and Org mode version 9.2.3 (9.2.3-11-g42abf5-elpaplus @ /.../.emacs.d/elpa/org-plus-contrib-20190429/) – 147pm Apr 29 at 19:17
  • I can run check-parens and get the problem. Go into C-c ' problem disappears. – 147pm Apr 29 at 20:06
3

The reason for the mismatch is the code contains an angled bracket (">") which is treated as a matching paren.

I don't know the solution for how to specify that orgmode emacs-elisp should ignore angled brackets when matching parens (but I would like to know a solution).

Note: I posted this as an "answer" because I don't have enough reputation points to post it as a comment in the OP.

2

Here is a potential solution:

(defun org-mode-<>-syntax-fix (start end)
  (when (eq major-mode 'org-mode)
    (save-excursion
      (goto-char start)
      (while (re-search-forward "<\\|>" end t)
    (when (get-text-property (point) 'src-block)
      ;; This is a < or > in an org-src block
      (put-text-property (point) (1- (point))
                 'syntax-table (string-to-syntax "_")))))))

(add-hook 'org-mode-hook
      (lambda ()
        (setq syntax-propertize-function 'org-mode-<>-syntax-fix)
        (syntax-propertize (point-max))))

This basically just changes the syntax table for <> inside src blocks I think. It seems to solve the problem.


The code above depends on source blocks already propertized with src-block.

The src-block property is put on source blocks by org-fontify-meta-lines-and-blocks during keyword fontification through font-lock. But, syntax fontification comes before keyword fontification. So maybe the following function is better. For easier copy-paste the full code is given. The main change is the search for source blocks by re-search-backward.

(defun org-mode-<>-syntax-fix (start end)
  "Change syntax of characters ?< and ?> to symbol within source code blocks."
  (let ((case-fold-search t))
    (when (eq major-mode 'org-mode)
      (save-excursion
        (goto-char start)
        (while (re-search-forward "<\\|>" end t)
          (when (save-excursion
                  (and
                   (re-search-backward "[[:space:]]*#\\+\\(begin\\|end\\)_src\\_>" nil t)
                   (string-equal (match-string 1) "begin")))
            ;; This is a < or > in an org-src block
            (put-text-property (point) (1- (point))
                               'syntax-table (string-to-syntax "_"))))))))

(defun org-setup-<>-syntax-fix ()
  "Setup for characters ?< and ?> in source code blocks.
Add this function to `org-mode-hook'."
  (setq syntax-propertize-function 'org-mode-<>-syntax-fix)
  (syntax-propertize (point-max)))

(add-hook 'org-mode-hook #'org-setup-<>-syntax-fix)
  • 1
    Dear John, your solution is very nice! I just added a small bugfix. I hope you do not mind. I did not write a new solution since the main idea is yours. – Tobias Oct 4 at 16:36
  • No problem, thanks for the improvement! – John Kitchin Oct 5 at 13:23
0

Since I never use <> as brackets in org mode documents, I have these two lines in my org mode hook function:

(modify-syntax-entry ?< ".")
(modify-syntax-entry ?> ".")

No need to play around with properties etc. Of course, if you use XML or HTML, you may wish to avoid this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.