Emacs: Как выдернуть последний дернутый текст, независимо от последующих убийств?

Я часто обнаруживаю, что неоднократно дергаю что-то после совершения некоторых убийств, и это становится процессом вроде:

  • С-у
  • C-y M-y
  • C-y M-y M-y
  • C-y M-y M-y M-y

Каждый раз, когда я убиваю какой-то текст, он толкает первое убивание в кольцо убийства, так что мне нужно пройти все убийства, чтобы вернуться к тексту, который я хочу вырвать. То, что я хочу сделать, неоднократно выдергивает один и тот же текст, убивая текст между янки. Возможно ли это?

Ответ 1

Это странный хак, но может помочь.

В первый раз, когда вы используете M-y, вы обычно получаете сообщение об ошибке (без предыдущего yank). Поэтому идея состоит в том, что в первый раз вы получите последний yank вместо последнего убийства.

Для сохранения этого последнего янка я использую регистр "Y" в этом примере.

Эти 2 функции обернут вокруг yank и yank-pop. Вы ожидаете ошибок, я ожидаю предложений.

(defun jp/yank (&optional arg)
  "Yank and save text to register Y"
  (interactive)
  (set-register ?Y (current-kill 0 t))
  (yank arg))

(defun jp/yank-pop (&optional arg)
  "If yank-pop fails, then insert register Y"
  (interactive)
  (condition-case nil
      (yank-pop arg)
    (error (insert (get-register ?Y)))))

(global-set-key (kbd "M-y") (quote jp/yank-pop))
(global-set-key (kbd "C-y") (quote jp/yank))

Ответ 2

Не используйте кольцо уничтожения; вместо этого введите текст в регистр. C-x r s a для сохранения текста региона в (скажем) регистр "a"; затем C-x r i a, чтобы вставить его в другое место.

Ответ 3

Вместо этого вы можете использовать M-x delete-region, чтобы убить текст, возможно привязывая его к ключу, если вы хотите использовать его много.

Ответ 4

  • Если вы хотите повторно отображать один и тот же текст, используйте вторичный выбор вместо региона или убитый текст.

    То, что отсутствует в vanilla Emacs, является ключевым связующим звеном для выделения вторичного выделения. Для этого я использую C-M-y (см. Библиотеку second-sel.el).

  • Чтобы получить прямой доступ к любым убийствам в кольце убийств, используйте M-y с Browse Kill Ring или Icicles. В обоих случаях M-y на верхнем уровне дает вам доступ ко всем записям в кольце уничтожения.

    И если вы используете библиотеку second-sel.el, то в дополнение к кольцу убийства вы получите доступ к кольцу прошлых вторичных выборов.

    И если вы используете библиотеки second-sel.el и Icicles, то M-y записывает запись из кольца, в котором вы последний раз дергались (кольцо убийства или кольцо вторичного выбора).

    И если вы используете библиотеку browse-kill-ring +.el, то браузер kill-ring также дает вам доступ к альтернативному кольцу (который, по умолчанию, это кольцо вторичных выборов, если вы используете библиотеку second-sel.el).

Ответ 5

Я пытаюсь взломать линию использования второстепенного режима. Позвольте называть это delete-mode. После того, как вы перейдете в режим удаления, команды kill (kill-line, kill-paragraph, kill-word,...) изменят свое поведение, так что часть их команд kill-region будет заменена на delete-region, а новая материал не будет добавлен в кольцо убийства. В этом режиме кольцо убийства останется постоянным. Когда вы переключаетесь обратно из этого режима, поведение возвращается в нормальное состояние.

Ниже приведен неполный код, который пытается реализовать то, что я написал выше. Он работает правильно при переключении в режим удаления, но у него есть проблема с переключением (отключение второстепенного режима). Любая помощь, исправляющая это, будет оценена.

(defvar delete-mode nil)

(defun delete-mode ()
    "delete minor-mode"
    (interactive)
    (setq delete-mode (not delete-mode))
    (if delete-mode
        (defalias 'kill-region 'delete-region)
        (defalias 'kill-region 'original-kill-region)
    )
)

(if (not (assq 'delete-mode minor-mode-alist))
    (setq minor-mode-alist
        (cons '(delete-mode "Delete mode on") minor-mode-alist)
    )
    (defalias 'original-kill-region 'kill-region)
)

Ответ 6

Я попытаюсь использовать область delete больше, но я знаю, что команды kill лучше. Трюк, который не требует программирования или предварительного планирования, заключается в использовании M-w после особенно раздражающей строки M-y. Это ставит более доступную копию финального янки в кольцо уничтожения.

Ответ 7

Лучшая реализация Yank-Pop

Это определяет лучшую реализацию yank-pop, которая пытается исправить возрастающую проблему yank-pop.

Он только отменяет функцию "current-kill". Из-за модульной конструкции переменных yank, yank-pop и kill ring и функций в Emacs оказывается, что переопределение "current-kill" - это все, что необходимо для получения желаемого поведения.

Желаемое поведение состоит в том, что (1) убийство чего-то еще ставит его перед кольцом убийства, но теперь (2) дергание или выскакивание чего-то также ставит его перед кольцом смерти (3), мы сохраняем способность yank-pop придавать внешнему виду движение по кольцу уничтожения путем увеличения глобальной переменной и использования этого, чтобы заменить последний элемент yank-pop'ped назад, где он был. Это также означает, что (4) элементы, которые являются переходными yanked (то есть элементы, помещенные командами yank или yank-pop, где следующая команда является yank-pop), в конечном итоге должны оставаться там, где они находятся в кольце kill.

;; Example:
;; (setq kill-ring '("a" "b" "c" "d" "e"))
;;
;; keystroke        kill ring contents              value of kill-ring-yank-index
;; C-y              ("a" "b" "c" "d" "e")           0
;; M-y              ("b" "a" "c" "d" "e")           1
;; M-y              ("c" "a" "b" "d" "e")           2
;; M-y              ("d" "a" "b" "c" "e")           3

;; C-y              ("d" "a" "b" "c" "e")           0
;; M-y              ("a" "d" "b" "c" "e")           1

;; M-d              ("x" "a" "d" "b" "c" "e")
;; etc.

код:

;; ----------------------------------------------------------------
;; helper functions

(defun list-insert-before (l n x)
  (if (<= n 0) (cons x l)
    (cons (car l) (list-insert-before (cdr l) (- n 1) x))))

(defun list-prepend-nth (l n)
  (if (<= n 0) l
    (let* ((lx (list-prepend-nth (cdr l) (- n 1))))
      (cons (car lx) (cons (car l) (cdr lx))))))

(defun list-insert-car-at (l n)
  (list-insert-before (cdr l) n (car l)))


;; ----------------------------------------------------------------
;; overriding current-kill

(defvar kill-ring-yank-index 0
  "Index into kill-ring of last yank-pop. The item yank-popped
  will be at the head of the kill ring, but if the next command
  is also yank-pop, it will be returned here first before this
  variable is incremented.")

(defun current-kill (n)
  "Replaces standard 'current-kill' function. This version tries
to fix the increasing yank-pop problem.

TODO:
- respect second argument of original function
- deal with 'interprogram-{cut,paste}-function'
"
  (if (eq 0 n) ;; looks like we're doing a yank; reset
               ;; kill-ring-yank-index to 0 to indicate that the
               ;; current head of the list is useful to the user
      (progn (setq kill-ring-yank-index 0)
             (car kill-ring))

    ;; otherwise put the head of kill-ring back where we had
    ;; previously found it, and fetch the next element
    (setq kill-ring
        (list-insert-car-at kill-ring kill-ring-yank-index))
    (setq kill-ring-yank-index (+ kill-ring-yank-index n))
    (when (>= kill-ring-yank-index (- (length kill-ring) 1))
      (setq kill-ring-yank-index (- (length kill-ring) 1))
      (message "Reached end of kill-ring"))
    (when (< kill-ring-yank-index 0)
      (setq kill-ring-yank-index 0)
      (message "Reached beginning of kill-ring"))
    (setq kill-ring (list-prepend-nth kill-ring kill-ring-yank-index))
    (car kill-ring)))

;; ----------------------------------------------------------------
;; new key binding

;; Here an auxiliary function and key binding that makes it easy to
;; go back and forth in the kill-ring while we're yank-popping
(defun yank-pop-back () "" (interactive "*")
       (yank-pop -1))

(global-set-key "\C-\M-y" 'yank-pop-back)

Ответ 8

Я использую

M-x browse-kill-ring

с привязкой клавиш "M-y". Существует также поддержка шлема.

https://www.emacswiki.org/emacs/BrowseKillRing

предлагает больше решений.