Дублирование строки в emacs с помощью Ace-Jump

Я довольно новичок в elisp, но одна вещь, которую я действительно хочу выяснить, это либо дождаться окончания 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)
)

Но это дает мне странное поведение


person user1539179    schedule 21.02.2014    source источник
comment
Для будущих читателей: ace-jump давно не поддерживается, пожалуйста, не используйте его. В наши дни вам нужен avy режим.   -  person Hi-Angel    schedule 17.12.2020


Ответы (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))
person abo-abo    schedule 21.02.2014

Я использую что-то похожее на 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))))))
person Dan    schedule 21.02.2014
comment
Из любопытства, что похоже на ace-jump, но не на ace-jump? - person PythonNut; 21.02.2014
comment
Длинная и скучная история; короткая версия заключается в том, что я писал пакет, чтобы делать то, что делает ace-jump, когда последний вышел. Никогда не удосужился его выпустить, но и не удосужился переключиться. - person Dan; 21.02.2014
comment
По какой-то причине ace-jump не любит играть с save-excursion. Курсор не возвращается в исходное положение. Он просто остается там, где его помещает ace-jump. - person user1539179; 22.02.2014

Хорошо, ничего из этого не сработало для меня, но я использовал эти ответы, чтобы создать работающий скрипт. Вот код, который я использовал:

;; 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 каждый раз, когда он вызывается. Это работает для меня, хотя, поскольку у меня нет ничего другого, подключенного к нему. Если у меня возникнут проблемы, мне нужно будет придумать что-то еще.

person user1539179    schedule 24.02.2014

ace-jump-mode действительно глупый... вызов его просто переходит в какой-то бесполезный второстепенный режим, где вы выбираете подсказки, но он не блокирует: любой последующий код выполняется немедленно.

Существует так много потенциала для такого взаимодействия, и режим ace-jump полностью растрачивает его с сумасшедшей реализацией. Это также не работает с save-excursion, и вам нужно взломать это с помощью различных хуков и переменных, сохраняющих состояние.

Я написал новый пакет для решения всех этих проблем, вы можете найти его по адресу https://github.com/Fuco1/better-jump Надеюсь, люди это поймут, но, по крайней мере, мне он служит хорошо. На написание базового рабочего прототипа у меня ушло около 2 часов, и он уже охватывает всю функциональность таких пакетов, как ace-link, ace-window и ace-whatever-else-you-can-find (также ace-jump, разумеется :))

person Matus Goljer    schedule 08.07.2014