1

我有以下代码/文本:

def f():
    """
    Return nothing.

    .. NOTE::

        First note line
second note line

在 Emacs23 (23.4.1) 中,我能够在最后一行(“第二个注释行”;不管这行如何缩进)按 TAB,并且它像这样正确对齐:

def f():
    """
    Return nothing.

    .. NOTE::

        First note line
        second note line

即,它使用上一行并以相同的方式缩进下一行。

现在在 Emacs24 (24.3.1) 中,这不再起作用,它的对齐方式如下:

def f():
    """
    Return nothing.

    .. NOTE::

        First note line
    second note line

即它对齐多行字符串块,但不依赖于前一行。

它只影响文档字符串;代码按我的意愿缩进。我正在使用python-mode. 我怎样才能改变它,以便按 TAB 正确对齐块?

4

2 回答 2

0

在单独的缓冲区中编辑去字符串化的部分怎么样?这将允许 python-mode 及其所有设施。

这里是初稿 - 原始字符串将存储在 kill-ring 中:

(defun temp-edit-docstring ()
  "Edit docstring in python-mode. "
  (interactive "*")
  (let ((orig (point))
    (pps (parse-partial-sexp (point-min) (point))))
    (when (nth 3 pps)
      (let* (;; relative position in string
         (relpos (- orig (+ 2 (nth 8 pps))))
         (beg (progn (goto-char (nth 8 pps))
             (skip-chars-forward (char-to-string (char-after)))(push-mark)(point)))

         (end (progn (goto-char (nth 8 pps))
             (forward-sexp)
             (skip-chars-backward (char-to-string (char-before)))
             (point)))

         (docstring (buffer-substring beg end)))
    (kill-region beg end)
    (set-buffer (get-buffer-create "Edit docstring"))
    (erase-buffer)
    (switch-to-buffer (current-buffer))
    (insert docstring)
    (python-mode)
    (goto-char relpos)))))

准备好后,将内容复制回原始缓冲区。这仍有待实施。

于 2015-08-19T06:55:10.147 回答
0

Python 模式在 Emacs 23 和 24 之间发生了相当大的变化。没有任何配置可以让你做你想做的事。

但是,Emacs 非常灵活,您可以建议该(python-indent-context)函数使其返回不同的结果,从而导致您想要的行为。该函数(python-indent-context)返回一个字符,在该字符处测量缩进并用于缩进当前行。默认情况下,当在字符串中时,它返回字符串开头所在的点。因此,您的行将缩进到字符串开头的缩进处。我们可以很容易地修改它以返回前一个非空行中的一个点,例如:

(defun python-fake-indent-context (orig-fun &rest args)
  (let ((res (apply orig-fun args)))  ; Get the original result
    (pcase res
      (`(:inside-string . ,start)  ; When inside a string
       `(:inside-string . ,(save-excursion  ; Find a point in previous non-empty line
                             (beginning-of-line)
                             (backward-sexp)
                             (point))))
      (_ res))))  ; Otherwise, return the result as is

;; Add the advice
(advice-add 'python-indent-context :around #'python-fake-indent-context)

使用旧 Emacs 的旧 defadvice 可以达到相同的效果:

(defadvice python-indent-context (after python-fake-indent-context)
  (pcase ad-return-value
    (`(:inside-string . ,start)  ; When inside a string
     (setq ad-return-value       ; Set return value
           `(:inside-string . ,(save-excursion  ; Find a point in previous non-empty line
                                 (beginning-of-line)
                                 (backward-sexp)
                                 (point)))))))
(ad-activate 'python-indent-context)
于 2015-08-17T21:25:32.097 回答