【问题标题】:emacs elisp send line if no region active python-mode如果没有区域处于活动状态,则 emacs elisp 发送行 python-mode
【发布时间】:2016-03-11 07:55:59
【问题描述】:

我想创建一个命令,如果该区域处于活动状态,则发送该区域,如果不是,则评估当前行/语句并将点进一步转移到下一个语句。

我从This solution.开始 现在我无法让 (python-shell-send-region) 工作,因为我不知道如何将区域的开头和结尾传递给它。

到目前为止,我有这个:

 (defun my-python-send-region (&optional beg end)   
   (interactive)   
    (if (use-region-p)
      (python-shell-send-region)    (let ((beg (cond (beg beg)
                    ((region-active-p)
                     (region-beginning))
                    (t (line-beginning-position))))
         (end (cond (end end)
                    ((region-active-p)
                     (copy-marker (region-end)))
                    (t (line-end-position)))))
     (python-shell-send-region beg end)
     (python-nav-forward-statement))))

 (add-hook 'python-mode-hook
       (lambda ()
     (define-key python-mode-map "\C-cn" 'my-python-send-region)))

更新: 根据 Andreas 和 Legoscia 的建议,我稍微改变了结构。

现在我得到一个错误 (Invalid function: (setq beg (point)) for:

 (defun my-python-send-region (&optional beg end)
  (interactive)
  (if (use-region-p)
    (python-shell-send-region (region-beginning) (region-end))
   ((setq beg (point))
    (python-nav-end-of-statement)
    (setq end (point))
    (python-shell-send-region (beg) (end)))
    (python-nav-forward-statement))))

但是,这是可行的:

 (defun my-python-send-region (&optional beg end)
 (interactive)
 (setq beg (point))
 (python-nav-end-of-statement)
 (setq end (point))
 (python-shell-send-region beg end))

【问题讨论】:

  • 由于 Python 对 WRT 空格的敏感性,发送区域或行容易出错。而是使用针对 Python 表单的命令——发送块、语句等。

标签: python emacs elisp


【解决方案1】:

另一种可行的方法是尝试 melpa 的整个行或区域包。这个包设置了一些东西,如果你调用一个需要一个区域但没有定义区域的命令,它基本上会设置一个等于当前行的区域。本质上,这会导致在当前行上没有定义区域时期望区域工作的命令。我的 init.org 文件中有这个

如果没有,则允许面向区域的命令在当前行上工作 区域已定义。

   #+BEGIN_SRC emacs-lisp
     (use-package whole-line-or-region
       :ensure t
       :diminish whole-line-or-region-mode
       :config
       (whole-line-or-region-mode t)
       (make-variable-buffer-local 'whole-line-or-region-mode))

【讨论】:

  • 它不会向前移动一行,但我可以通过在我经常使用它时录制一个快速宏来修复它
【解决方案2】:

在这部分:

(if (use-region-p)
  (python-shell-send-region)

您需要将区域的开头和结尾传递给python-shell-send-region。它仅在交互调用时自动获取这些值。当你从 Lisp 代码中调用它时,你需要显式地传递值:

(python-shell-send-region (region-beginning) (region-end))

【讨论】:

    【解决方案3】:

    更新答案:python-shell-send-defun 并不总是发送当前语句/行 (it is not meant to do that),所以我用 elpy 中的函数替换了它

    (defun python-shell-send-region-or-line nil
      "Sends from python-mode buffer to a python shell, intelligently."
      (interactive)
      (cond ((region-active-p)
         (setq deactivate-mark t)
         (python-shell-send-region (region-beginning) (region-end))
     ) (t (python-shell-send-current-statement))))
    
    (defun python-shell-send-current-statement ()
    "Send current statement to Python shell.
    Taken from elpy-shell-send-current-statement"
    (interactive)
    (let ((beg (python-nav-beginning-of-statement))
        (end (python-nav-end-of-statement)))
    (python-shell-send-string (buffer-substring beg end)))
    (python-nav-forward-statement))
    

    如果我想添加案例,我会使用 cond。设置 deactivate-mark 是如果选中则取消选择该区域。如果没有选择区域,我还会向前导航一条 python 语句。

    【讨论】:

    • 当我在没有活动区域的情况下使用它时,我得到错误:'参数数量错误:(1 . 1),0
    • “arg 的数量错误...”来自上一个答案中的移动行尾,需要一个参数 nil。更新后的答案无论如何都删除了该功能。
    • 这非常好 - 现在唯一的小故障是即使选择了一个区域,它也会向前跳一个语句,如果你继续前进,这可能会让你错过部分代码。
    • 在我的 emacs 上,当一个区域被选中时,它会将该区域发送给解释器并取消选择该区域而不向前移动一个语句。如果没有选择一个区域,那么它将发送当前语句并向前移动一个语句。如果您不想向前移动语句,请从 python-shell-send-current-statement 中删除 (python-nav-forward-statement)。或者您可能希望将 (python-nav-forward-statement) 替换为 (next-line) (move-end-of-line nil)
    猜你喜欢
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多