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
предлагает больше решений.