Emacs+AUCTeX:改进 ConTeXt 模式缩进

Emacs+AUCTeX:改进 ConTeXt 模式缩进

我使用 Emacs 和 AUCTeXConTeXt-mode编写我的 ConTeXt 文档。但是缩进对我来说有点不方便。

考虑以下代码片段:

\setuphead
  [section]
  [before={\blank[big]},
   after={\blank[medium]}]

\setuphead
  [subsection]
  [
    before={\blank[big]},
    after={\blank[medium]},
  ]

如果我执行indent-region这个,它应该不是更改(缩进正确,即遵循缩进方案ConTeXt 源以及我们本地 ConTeXt 专家提供的缩进方案阿迪亚)。然而,Emacs 将此代码改写为

\setuphead
  [section]
  [before={\blank[big]},
    after={\blank[medium]}]

  \setuphead
    [subsection]
    [
      before={\blank[big]},
      after={\blank[medium]},
    ]

尤其是第二行\setuphead此时不应该再缩进。

有人可以提供一些 Lisp 魔法让我的.emacs缩进不那么痛苦吗?

答案1

注意:这个问题导致了包容性AUCTeX 中的以下修复。它将在 ELPA 版本 11.90.3 和稳定版本 11.91 中可用。

警告:这个答案确实几乎你问的什么。

将以下函数定义添加到您的初始化文件中:

(with-eval-after-load "context"
  (defun ConTeXt-find-indent (&optional virtual)
    "Find the proper indentation of text after point.
VIRTUAL if non-nil indicates that we're only trying to find the
indentation in order to determine the indentation of something
else.  There might be text before point."
    (save-excursion
      (skip-chars-forward " \t")
      (or
       ;; Trust the current indentation, if such info is applicable.
       (and virtual (>= (current-indentation) (current-column))
        (current-indentation))
       ;; Put leading close-paren where the matching open brace would be.
       (condition-case nil
       (and (eq (char-syntax (char-after)) ?\))
        (save-excursion
          (skip-syntax-forward " )")
          (backward-sexp 1)
          (ConTeXt-find-indent 'virtual)))
     (error nil))
       ;; Default (maybe an argument)
       (let ((pos (point))
         (char (char-after))
         (indent 0)
         up-list-pos)
     ;; Look for macros to be outdented
     (cond ((looking-at (concat (regexp-quote TeX-esc)
                    (ConTeXt-environment-stop-name)))
        (setq indent (- indent ConTeXt-indent-basic)))
           ((looking-at ConTeXt-indent-item-re)
        (setq indent (- indent ConTeXt-indent-item))))
     ;; Find the previous point which determines our current indentation.
     (condition-case err
         (progn
           (backward-sexp 1)
           (while (or (> (current-column) (current-indentation))
              ;; Continue going back if we are
              ;; at a hanging optional group.
              (looking-at (regexp-quote ConTeXt-optop)))
         (backward-sexp 1)))
       (scan-error
        (setq up-list-pos (nth 2 err))))
     (cond
      ((= (point-min) pos) 0)  ; We're really just indenting the first line.
      ((integerp up-list-pos)
       ;; Have to indent relative to the open-paren.
       (goto-char up-list-pos)
       (if (and (not ConTeXt-indent-allhanging)
            (> pos (progn (down-list 1)
                  (forward-comment (point-max))
                  (point))))
           ;; Align with the first element after the open-paren.
           (current-column)
         ;; We're the first element after a hanging brace.
         (goto-char up-list-pos)
         (+ indent ConTeXt-indent-basic (ConTeXt-find-indent 'virtual))))
      ;; We're now at the "beginning" of a line.
      ((not (and (not virtual) (eq (char-after) ?\\)))
       ;; Nothing particular here: just keep the same indentation.
       (+ indent (current-column)))
      ;; We're now looking at an item.
      ((looking-at ConTeXt-indent-item-re)
       ;; Indenting relative to an item, have to re-add the outdenting.
       (+ indent (current-column) ConTeXt-indent-item))
      ;; We're looking at an environment starter.
      ((and (looking-at (concat (regexp-quote TeX-esc)
                    (ConTeXt-environment-start-name)))
        (not (looking-at (concat (regexp-quote TeX-esc)
                     (ConTeXt-environment-start-name)
                     ConTeXt-text)))) ; other environments?
       (+ indent (current-column) ConTeXt-indent-basic))
      (t
       (let ((col (current-column)))
         (if (not (and char (eq (char-syntax char) ?\()))
         ;; If the first char was not an open-paren, there's
         ;; a risk that this is really not an argument to the
         ;; macro at all.
         (+ indent col)
           (forward-sexp 1)
           (if (< (line-end-position)
              (save-excursion (forward-comment (point-max))
                      (point)))
           ;; we're indenting the first argument.
           (min (current-column) (+ ConTeXt-indent-arg col))
         (skip-syntax-forward " ")
         (current-column)))))))))))

这是 AUCTeX 提供的缩进功能的修复版本。 仅(looking-at (regexp-quote ConTeXt-optop))在 之后有一个小改动(行)来调整缩进[...]

现在你的原始代码缩进为

\setuphead
  [section]
  [before={\blank[big]},
    after={\blank[medium]}]

\setuphead
  [subsection]
  [
    before={\blank[big]},
    after={\blank[medium]},
  ]

我唯一无法修复的是after={\blank[medium]}]行的缩进,但是对于里面的多行设置,[...]我建议您像第二种情况那样做。

请告诉我您是否发现此解决方案从长远来看有用,以便我可以在上游安装此更改。

相关内容