いくつかのキルを行った後、何かを繰り返しヤンクしていることに気付くことがよくあります。それは次のようなプロセスになります。
- Cy
- サイマイ
- Cy My My
- Cy My My My
テキストをキルするたびに、最初のキルがキルリングに押し戻されるため、ヤンクしたいテキストに戻るには、すべてのキルを循環する必要があります。私がやりたいのは、ヤンクの間のテキストを殺しながら、同じテキストを繰り返しヤンクすることです。これは可能ですか?
キルリングは使用しないでください。代わりに、テキストをレジスターに入れてください。 C-x r s a
リージョンのテキストを(たとえば)レジスタ「a」に格納します。次にC-x r i a
、それを別の場所に挿入します。
これは奇妙なハックですが、役に立つかもしれません。
初めて使用M-y
すると、通常はエラーが発生します (以前のヤンクはありません)。つまり、最後のキルではなく、最後のヤンクを初めて取得するという考えです。
最後のヤンクを保存するために、この例では「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))
代わりに使用M-x delete-region
して、テキストを強制終了し、頻繁に使用する場合はキーにバインドすることもできます。
同じテキストを繰り返しヤンクしたい場合は、リージョンまたはキルされたテキストの代わりに二次選択を使用します。
通常の Emacs に欠けているのは、二次選択をヤンクするためのキー バインドです。私はC-M-y
そのために使用します(ライブラリを参照second-sel.el
)。
キル リング内のキルに直接アクセスするには、 Browse Kill RingまたはIciclesを使用M-y
します。どちらの場合も、トップ レベルでキル リングのすべてのエントリにアクセスできます。M-y
また、ライブラリを使用するsecond-sel.el
と、キル リングに加えて、過去のセカンダリ セレクションのリングにアクセスできます。
また、ライブラリsecond-sel.el
とIciclesを使用する場合M-y
は、最後にヤンクしたリング (kill リングまたはセカンダリ選択リング) からエントリをヤンクします。
また、 library browse-kill-ring+.elを使用すると、kill-ring ブラウザーは別のリングにもアクセスできるようにします (これは、デフォルトでは、 library を使用する場合の二次選択のリングですsecond-sel.el
)。
もっとdelete-regionを使おうと思いますが、killコマンドはよく知っています。プログラミングや事前の計画を必要としないトリックは、特に煩わしい My の文字列の後に Mw を使用することです。これにより、最終ヤンクのよりアクセスしやすいコピーが kill リングに配置されます。
これは、増加するヤンクポップの問題を解決しようとする、より良いヤンクポップの実装を定義します。
関数「current-kill」をオーバーライドするだけです。Emacs の yank、yank-pop、および kill リング変数と関数のモジュール設計により、"current-kill" をオーバーライドするだけで、必要な動作を得ることができます。
望ましい動作は、(1) 何かを強制終了すると、それは依然としてキル リングの先頭に置かれますが、(2) 何かをヤンクまたはヤンクポップすると、それもキル リングの先頭に置かれます (3) の機能を保持します。 yank-pop を使用して、グローバル変数をインクリメントし、これを使用して最後に yank-pop されたアイテムを元の場所に戻すことで、キル リングを移動するように見せます。これはまた、(4) 一時的にヤンクされたアイテム (つまり、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's 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)
マイナーモードを使用してハッキングしようとしています。これを と呼びましょう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)
)