使用Ace-Jump在emacs中复制一行

时间:2014-02-21 00:28:48

标签: emacs elisp

我对elisp很新,但有一点我真正想知道的是如何在执行指令之前等待ace-jump结束或者如何从ace-jump获取位置而不是移动我的光标。我的目标是能够选择具有ace-jump的行,复制它,然后将其粘贴在我当前行的正上方。我开始时首先尝试使用ace-jump进入一条线,然后将其复制到位,但这没有用。以下是我的意见:

(defun ace-jump-yank-line-above ()
  (interactive)
  (ace-jump-line-mode)
  (kill-ring-save (line-beginning-position) (line-beginning-position 2) )
  (yank)
)

但这给了我奇怪的行为

4 个答案:

答案 0 :(得分:4)

您可以查看我的项目lispy.el的来源。 它有几个函数使用ace-jump-mode并在之后执行某些操作。 例如lispy-ace-symbol将跳转到符号并标记它。 以下是实施细节 - 关键是设置ace-jump-mode-hook

(defun lispy--ace-do (x bnd &optional filter func no-narrow)
  "Use `ace-jump-do' to X within BND when FILTER return t.
When FUNC is not nil, call it after a successful move.
When NO-NARROW is not nil, don't narrow to BND."
  (require 'ace-jump-mode)
  (lispy--recenter-bounds bnd)
  (unless no-narrow
    (narrow-to-region (car bnd) (cdr bnd)))
  (when func
    (setq ace-jump-mode-end-hook
          (list `(lambda()
                   (setq ace-jump-mode-end-hook)
                   (,func)))))
  (let ((ace-jump-mode-scope 'window)
        (ace-jump-search-filter filter))
    (ace-jump-do x))
  (widen))

答案 1 :(得分:2)

我使用的东西类似于ace-jump而不是ace-jump本身,但是这样的东西应该可以工作(不能确定调用ace-jump-line-mode):

(defun ace-jump-yank-line-above ()
  (interactive)
  (let ((loc (point-at-bol))
        (line nil))
    (save-excursion
      (ace-jump-line-mode)
      (setq line (buffer-substring-no-properties
                  (point-at-bol) (point-at-eol)))
      (goto-char (1- loc))
      (if (bobp)
          (insert (concat line "\n"))
        (insert (concat "\n" line))))))

答案 2 :(得分:0)

好的,这些都不适合我,但我使用这些答案来创建一个有效的脚本。这是我使用的代码:

;; The base function for the line-based ones
(defun ace-jump-end-do (dfunc afunc)

  ;; Save where to return to as a marker
  (setq ace-jump-do-retpos (make-marker))
  (set-marker ace-jump-do-retpos (point))
  ;; Add our during function to the hook
  (setq ace-jump-mode-end-hook
        (list `(lambda()
                 (progn
                 (setq ace-jump-mode-end-hook)
                 (,dfunc)
                 (goto-char ace-jump-do-retpos)
                 (set-marker ace-jump-do-retpos nil)
                 (,afunc)
                 ))))

  (ace-jump-line-mode)
  )

;; Copy the line above the current line
(defun ace-jump-yank-line-above ()
  (interactive)
  (ace-jump-end-do
   ;; At the line
   (lambda ()
     ;; Store the line in a variable
     (setq line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
     )

   ;; Upon returning
   (lambda ()
     (save-excursion
       (goto-char (point-at-bol))
       (insert (concat line "\n"))
       )
     (when (bolp) (goto-char (point-at-bol 2)))
  )))

不幸的是,这会在每次调用时重置ace-jump的结束钩子。它适用于我,因为我没有其他任何东西吸引它。如果我遇到问题,我需要解决其他问题。

答案 3 :(得分:0)

ace-jump-mode非常愚蠢......调用它只是进入一些无用的小模式,你选择提示,但它是非阻塞的:之后的任何代码都会立即执行。

这种交互有很多潜力,而且ace-jump-mode完全浪费了疯狂的实现。它在使用save-excursion时根本不起作用,你需要通过各种钩子和状态保存变量来解决这个问题。

我已经写了一个解决所有这些问题的新软件包,你可以在https://github.com/Fuco1/better-jump找到它。希望人们会接受它,但它至少对我有好处。花了我大约2个小时来编写基本的工作原型,它已经涵盖了所有的功能,如ace-link,ace-window和ace-whatever-else-you-you-you-find-also(也是ace-jump,显然:))