emacs 24:如何恢复 python 模式下的 emacs-23 sexp 行为?

emacs 24: How do I get back emacs-23 sexp behavior for python mode?

我 运行 emacs 23 和 24 都使用“--no-init-file”以避免加载我的自定义设置。但是后来我明确加载了 python-mode.el 的旧版本(版本 3.105,最后的版权声明 1998),并看到了我将要描述的相同行为,所以我相信它是核心 emacs,而不是python.

考虑这段代码(* 标记光标位置):

*def emacs_is_fun():
    for x in range(3):
        print(x)

将光标置于 "def" 开头的第 4 列。

对于 emacs 23,运行 mark-sexp 选择 "def"。

用emacs 24,mark-sexp选择整个代码块,到最后 打印语句。

这还不错。主要问题是这种常见用法:

    *very_long_var_name[very_long_expn] += long_function_call(long_arg_list, blah)

同样,光标位于该行可打印部分的开头,col 4。

在 emacs 23 中,mark-sexp 选择 very_long_var_name

在 emacs 24 中,mark-sexp 选择整行,从第 4 列到最后。

我一直在使用 Ctrl-alt-space alt-w 来快速保存变量名。 (或者 alt-2 ctrl-alt-space alt-w 来保存一个 ref 表达式。)现在是 走了。是emacs,所以这个肯定是可以定制的,但是我没找到 实现新行为的地方(记住我使用的是 python-模式 那大约是 15 岁)。我需要在我的 .emacs 文件中放入什么?

这似乎是 emacs 24 中的错误修复。因为这在技术上现在标记完整的 sexp。您似乎想要标记符号的功能。

认为 通过将其放入您的 .emacs 您将获得所需的功能。

(defun your-mark-symbol (&optional arg allow-extend)
  "mark-sexp in lisp.el but with fowrad-symbol instead of foward-sexp"
  (interactive "P\np")
  (cond ((and allow-extend
          (or (and (eq last-command this-command) (mark t))
          (and transient-mark-mode mark-active)))
     (setq arg (if arg (prefix-numeric-value arg)
             (if (< (mark) (point)) -1 1)))
     (set-mark
      (save-excursion
        (goto-char (mark))
        (forward-symbol arg)
        (point))))
    (t
     (push-mark
      (save-excursion
        (forward-symbol (prefix-numeric-value arg))
        (point))
      nil t))))

(global-set-key (kbd "C-M-SPC") 'your-mark-symbol)

请注意,它实际上是 mark-sexp 的副本,但带有 foward-symbol 而不是 forward-sexp

如果您通过 C-M-SPC 在其他 buffers/modes 中使用 mark-sexp,这很可能会导致意外的怪异,在这种情况下,您会想要改为通过模式挂钩进行此键绑定。

@Eric 有趣。感谢我的其他答案的评论中的上下文。

我想你可能只想要这个:

(add-hook 'python-mode-hook (lambda () (setq forward-sexp-function nil)))

来自 python-mode 内置 emacs 24 中的评论(我认为您可能会得到它)

At last but not least the specialized python-nav-forward-sexp allows easy navigation between code blocks. If you prefer cc-mode-like forward-sexp movement, setting forward-sexp-function to nil is enough...

这更接近我对 sexp 的看法,就像我在其他答案中提到的那样,但在 lisp 之外,sexp 似乎至少有些模棱两可。