【问题标题】:Copy Character Down in Emacs在 Emacs 中复制字符
【发布时间】:2011-12-26 07:58:56
【问题描述】:

我编写了一个交互式函数,它将“点上方的字符”插入到当前行。例如,给定包含“12345”的行,后跟“abcdef”行和位于字母“c”处的点,向下复制将使第二行变为“ab3cdef”。再次向下复制将使第二行变为“ab34cdef”。

我的函数在第二次调用它时失败(在 Windows 7 下使用 GNU Emacs 23.3.1),我通过插入第一次调用中的文本并且没有正确推进来调用它。如果我在调用之间放置任何 emacs“操作”,它就可以正常工作。 (例如,如果我执行向下复制、“左箭头”、“右箭头”、向下复制,这两种调用都可以正常工作。)

这是我的功能:

(defun copy-down ()
  "Grab the character in the line above and insert at the current location."
  (interactive)
  (let ((beg (progn (previous-line 1) (point)))
        (end (progn (forward-char) (point))))
    (backward-char)
    (next-line 1)
    (insert-buffer-substring (current-buffer) beg end)))

如果重要的话,我通常将我的函数绑定到一个键:(global-set-key [f5] 'copy-down)

PS。我已经习惯了在多年前切换到 emacs 之前使用的编辑器中使用此功能,而我在 GNU Emacs 中很怀念它。 :-(

【问题讨论】:

    标签: emacs


    【解决方案1】:

    你所拥有的对我来说很好用。也就是说,previous-line 与其他设置(特别是goal-column)有交互,通常在编写 elisp 时不应该使用。相反,您应该使用(forward-line -1)。但是,当然,您的代码依赖于goal-column...您可以通过在没有其他配置的情况下运行 Emacs 来测试它,ala emacs -q

    这里有一个稍微不同的代码版本,它不依赖于goal-column

    (defun copy-down ()
      "Grab the character in the line above and insert at the current location."
      (interactive)
      (let* ((col (current-column))
             (to-insert (save-excursion
                         (forward-line -1)
                         (move-to-column col)
                         (buffer-substring-no-properties (point) (1+ (point))))))
        (insert to-insert)))
    

    如果问题不在于使用previous-line,那么我认为我的代码不会有太大的不同。

    您的另一个选择是尝试在调试器中运行它以查看您的代码在哪里出现故障。将defun 中的点移动到copy-down 并键入M-x edebug-defun,下次运行它时,您将能够单步执行代码。 edebug 的文档可以在 here 找到。

    【讨论】:

      【解决方案2】:

      您需要使用let* 而不是let。前者允许您在同一语句中的后续形式中使用较早的值。

      顺便说一句,这是一种非常规的 elisp 编写方式,您可能需要查看其他一些代码示例。

      编辑: 嘿,有人完全重新安排了你的功能!它现在可能工作了。

      【讨论】:

        【解决方案3】:

        试试

        (defun copy-down (arg)
          (interactive "p")
          (let ((p (+ (current-column) (point-at-bol 0))))
            (insert-buffer-substring (current-buffer) p (+ p arg))))
        

        它具有使用前缀参数复制 n(默认为 1)个字符的附加功能。

        【讨论】:

        • 我喜欢!感谢您的修复和改进!
        • @huaiyuan 最好用(decf arg) (let ((p (min (+ (current-column) (point-at-bol (- arg))) (point-at-eol (- arg))))) (insert-buffer-substring (current-buffer) p (1+ p)))。我认为arg 应该代表目标行。宏编辑更好,我个人从不使用arg,而是按住键2-3秒。其次,我在这里使用min。这显然是需要的措施,您将自己移到下一行。顺便说一句,感谢代码,不知道point-at-bol 有这么好的参数。 @user1040087 如果你喜欢,请接受答案。
        猜你喜欢
        • 2015-05-22
        • 2013-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-22
        相关资源
        最近更新 更多