最小限のキーストロークで現在の行を削除またはコピーします


32

私はC-a C-k C-k行全体を殺すためにポイントがオンになっています。

行を殺すのではなくコピーしたい場合はC-/ C-/ 、上記のシーケンスを入力した直後にヒットできます。

または、私はすることができますC-a C-SPC C-n M-w

ラインポイント全体を殺すかコピーするより速い方法はありますか?


1
うわー!これらの答えは、組み込みのを使用しないようにするために人々が進むであろう長さを示していkill-whole-lineます。:)
オマー

以下に示すように、を使用しますevil-mode。Vimコマンドを学ぶ、後悔しないでください!
A.ブリザード

回答:


44

を使用kill-whole-lineして、ラインポイントがオンになっている行全体を強制終了できます。ポイントの位置は関係ありません。このコマンドはC-S-DELデフォルトでバインドされています。

変数を値以外に設定して、行全体を強制終了するように指示することもできますkill-line(にバインドC-k)。 kill-whole-linenil

(setq kill-whole-line t)

これが機能するには、ポイントが行の先頭にある必要があることに注意してください。


次に、次の2つのgemがあります(emacs-fu経由):

(defadvice kill-region (before slick-cut activate compile)
  "When called interactively with no active region, kill a single line instead."
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (list (line-beginning-position) (line-beginning-position 2)))))

(defadvice kill-ring-save (before slick-copy activate compile)
  "When called interactively with no active region, copy a single line instead."
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (message "Copied line")
     (list (line-beginning-position) (line-beginning-position 2)))))

これらを配置すると、1回のキーストロークでラインポイントをオンまたはオフにすることができます。

  • C-w 現在の行を削除します
  • M-w 現在の行をコピーします

そこに活性領域があり、場合ことを注意kill-regionしてkill-ring-save、彼らは通常、何をやっていきます:キルまたはそれをコピーします。


ポーティングslick-cutslick-copy新しいアドバイスシステム

Emacs 24.4は新しいアドバイスシステムを導入しています。一方でdefadvice まだ動作し、それはEmacsの将来のバージョンで新システムの賛成で廃止されるかもしれないという可能性があります。そのために、更新されたバージョンのslick-cutおよびを使用することをお勧めしますslick-copy

(defun slick-cut (beg end)
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (list (line-beginning-position) (line-beginning-position 2)))))

(advice-add 'kill-region :before #'slick-cut)

(defun slick-copy (beg end)
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (message "Copied line")
     (list (line-beginning-position) (line-beginning-position 2)))))

(advice-add 'kill-ring-save :before #'slick-copy)

2
なお、kill-region及びkill-ring-saveまだ作業領域があるない場合でも、「アクティブ」。これにより、その動作がオーバーライドされます。私は時々その動作を使用しますが、この方法で使用することに慣れていない場合は、おそらく違いに気付かないでしょう。
nispio 14年

@nispioとき/どのように拡大してくださいkill-region使用可能であるなど/便利なときmark-activeですnil
フィルハドソン

1
@PhilHudsonマークはアクティブにならずに設定できます(通常は設定されます)。C-SPCマークをアクティブにしてから非アクティブにするために2回実行してみてください。ファイル内の別の場所にカーソルを移動して実行するkill-regionと、マークがアクティブでなくても、ポイントとマークの間の領域が強制終了されます。セット(しかし活性化しない)マークがあることを、コマンドのいくつかの例yankisearch。これらの並べ替えコマンドを実行すると、マークがアクティブでない場合でも、マークの場所がわかり、多くのコマンド(などkill-region)で明示的にアクティブにせずにマークを使用できます。
nispio

@nispioに感謝します。もちろん。それは、可視領域のハイライトがいくつかのメジャーリリースに戻ってデフォルトになる前に、排他的にそうだった方法ですよね?「アクティブ」と「セット」を混同していました。
フィルハドソン

1
これは、これまでにSXに投稿された最大の回答です。真剣に。
ベンジャミンリンドクヴィスト

15

私が見つけた解決策は、プレフィックス引数を使用することです。

私にとって、半分の行を削除することは便利な機能ですが、行全体を削除する簡単な方法も必要です。だからkill-line、前置引数を与えられたときに目に見えるものをすべて殺すようにした 。

(defmacro bol-with-prefix (function)
  "Define a new function which calls FUNCTION.
Except it moves to beginning of line before calling FUNCTION when
called with a prefix argument. The FUNCTION still receives the
prefix argument."
  (let ((name (intern (format "endless/%s-BOL" function))))
    `(progn
       (defun ,name (p)
         ,(format 
           "Call `%s', but move to BOL when called with a prefix argument."
           function)
         (interactive "P")
         (when p
           (forward-line 0))
         (call-interactively ',function))
       ',name)))

(global-set-key [remap paredit-kill] (bol-with-prefix paredit-kill))
(global-set-key [remap org-kill-line] (bol-with-prefix org-kill-line))
(global-set-key [remap kill-line] (bol-with-prefix kill-line))
(global-set-key "\C-k" (bol-with-prefix kill-line))

この小さなマクロでは、C-kまだポイントからキルしますが、 C-3 C-k3行全体を飲み込みます。ボーナスとして、を実行することでkill-whole-line動作を取得し ますC-1 C-k


それは素晴らしいアイデアです、共有してくれてありがとう!:) 1つまたは複数の行をコピーするために、このソリューションをどのように機能させますか?kill-ring-save接頭引数を受け付けません...
itsjeyd

@itsjeyd 2つの答えをマージするために、同様のことができると確信しています。しかし、もう少し手間がかかります。
マラバルバ14年

最後の行はparedit-killを指します。それは意図されていますか?
ボッカペルタ-IT 14

1
ああ、わかった、ありがとう。しかし、期待どおりの動作が得られません。行の中央にポインターを置いてC-3 Ckを押すと、最初の行が完全に削除されません。これはどのように機能するはずですか、または何か間違っていますか?
ボッカペルタ-IT 14

1
あなたが正しい@Malabarba kill-visual-lineは、にバインドされていC-kます。直します。再度、感謝します。
ボッカペルタ-IT 14

15

whole-line-or-regionアクティブな領域がない場合に現在の行で動作するようにさまざまな組み込みコマンドをアドバイスするパッケージがあり、現在の行M-wをコピーしC-wて、たとえば強制終了します。私はこのパッケージを何年も使用していますが、これは不可欠です。

さらに、このパッケージは、数値のプレフィックスが処理対象の行数を示すようにM-2 M-wするため、2行をコピーします。ここでの他の回答は、その便利な機能を提供していません。

著者がgithubアカウントでパッケージのメンテナンスを引き継ぎ、作成者がメンテナンスを停止して応答しなくなった。

whole-line-or-region また、必要に応じて、この動作を他のコマンドに追加する機能も提供します。


あなたが何を言っているのかわからないので、そのためのMELPAの問題を提出してください。私はこのパッケージをMELPAから問題なく常にインストールしています。
sanityinc

9

これは、オーソドックスなemacsに対する答えではありません。ただし、evilのモーダル編集で冒とくする場合は、次のことができます。

  • dd キルライン用
  • cc コピーライン用

両方とも、キル/コピーする行数を前に付けることができます(たとえば、4cc次の4行をコピーします)。


5

@itsjeydの答えに加えて、これらの2つの機能を提案できますか?

(defun xah-copy-line-or-region ()
  "Copy current line, or text selection.
When `universal-argument' is called first, copy whole buffer (but respect `narrow-to-region')."
  (interactive)
  (let (p1 p2)
    (if (null current-prefix-arg)
        (progn (if (use-region-p)
                   (progn (setq p1 (region-beginning))
                          (setq p2 (region-end)))
                 (progn (setq p1 (line-beginning-position))
                        (setq p2 (line-end-position)))))
      (progn (setq p1 (point-min))
             (setq p2 (point-max))))
    (kill-ring-save p1 p2)))

(defun xah-cut-line-or-region ()
  "Cut current line, or text selection.
When `universal-argument' is called first, cut whole buffer (but respect `narrow-to-region')."
  (interactive)
  (let (p1 p2)
    (if (null current-prefix-arg)
        (progn (if (use-region-p)
                   (progn (setq p1 (region-beginning))
                          (setq p2 (region-end)))
                 (progn (setq p1 (line-beginning-position))
                        (setq p2 (line-beginning-position 2)))))
      (progn (setq p1 (point-min))
             (setq p2 (point-max))))
    (kill-region p1 p2)))

次に、重要な定義(おそらくそれらを調整する必要があります):

(global-set-key (kbd "<f2>") 'xah-cut-line-or-region) ; cut

(global-set-key (kbd "<f3>") 'xah-copy-line-or-region) ; copy

(global-set-key (kbd "<f4>") 'yank) ; paste

ErgoEmacs提供


ご回答有難うございます!これらのコマンドがここに掲載されている他のソリューションとどのように異なるかを説明することで、少し拡張することを検討する必要があります。はい、この情報はdocstringsで利用できますが、将来の読者にもっと見やすくするために害はありません:)
itsjeyd 14年

1
これを行うことは可能ですが、下の@Jonathanの投稿のように変更して、最初にsexpまたはwordを取得し、再度呼び出された場合に行を取得しますか?
J Spen

@JSpen私がやっているのは、ショートカットキーを機能に割り当てることです。ジョナサンがしていることは、機能へのアドバイスを定義することです。そのため、関数にアドバイスするだけで、アドバイスされた関数へのショートカットキーを定義できます。結果が得られます。遅れてごめんなさい;)
Nsukami _

4

上記の@itsjeydの答えの拡張として、次のものがあります。(おそらく、ロジックはわずかにクリーンアップされる可能性があり、新しいアドバイスシステムに移植するときは、再度繰り返される場合はsexp/ に拡張することも考えられますparagraph)。

最初のC-w/ M-wはポイントの単語のみを取得し、2回目の呼び出しは行全体を取得します。

;; *** Copy word/line without selecting
(defadvice kill-ring-save (before slick-copy-line activate compile)
  "When called interactively with no region, copy the word or line

Calling it once without a region will copy the current word.
Calling it a second time will copy the current line."
    (interactive
     (if mark-active (list (region-beginning) (region-end))
       (if (eq last-command 'kill-ring-save)
           (progn
             ;; Uncomment to only keep the line in the kill ring
             ;; (kill-new "" t)
             (message "Copied line")
             (list (line-beginning-position)
                   (line-beginning-position 2)))
         (save-excursion
           (forward-char)
           (backward-word)
           (mark-word)
           (message "Copied word")
           (list (mark) (point)))))))

;; *** Kill word/line without selecting
(defadvice kill-region (before slick-cut-line first activate compile)
  "When called interactively kill the current word or line.

Calling it once without a region will kill the current word.
Calling it a second time will kill the current line."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
    (if (eq last-command 'kill-region)
        (progn
          ;; Return the previous kill to rebuild the line
          (yank)
          ;; Add a blank kill, otherwise the word gets appended.
          ;; Change to (kill-new "" t) to remove the word and only
          ;; keep the whole line.
          (kill-new "")
          (message "Killed Line")
          (list (line-beginning-position)
                (line-beginning-position 2)))
      (save-excursion
        (forward-char)
        (backward-word)
        (mark-word)
        (message "Killed Word")
        (list (mark) (point)))))))

これを更新しましたか?もしそうなら、コピーはどこにありますか?また、これによりマークリングに大量のマークが追加されます。コピーした場所の先頭に1つのマークを追加することはできますか。そのため、単語の先頭または行の先頭。今では毎回4つのマークが追加されますが、これは迷惑です。実際に(backward-sexp)を使用するように変更しましたが、見つからない場合があり、エラーが発生します。行が見つからない場合、単に行をコピーできますか?私はこれを行う方法がわからず、単にエラーを無視してノイズを発生させませんでした。申し訳ありませんが、私はLispが得意ではありません。
J Spen

1

最小限のキーストロークでそれを行いたいので、David Anderssonの優れたキーコードパッケージを使用できます。「キーコード」とは、2つのキーを同時に押すか、1つのキーを2回押すことです。

任意のキーコードをこれらの機能にバインドできます。

(require 'key-chord)
(key-chord-mode 1)
(key-chord-define-global "dd"  'kill-whole-line)
(key-chord-define-global "cc"  'yank-whole-line)

答えてくれてありがとう:)私は過去数回キーコードを試しましたが、実際にそれらに慣れることができませんでした。しかし、回答がここに集められた場合、これは間違いなくセットへの便利な追加です!
itsjeyd

1

あまりアドホックではない方法は、を定義することですmark-whole-line。これには、Emacsが実際にデフォルトのコマンドを使用する必要があります。

(defun mark-whole-line ()               
    "Combinition of C-a, mark, C-e"
    (interactive)
    (move-beginning-of-line nil)
    (set-mark-command nil)
    (move-end-of-line nil)
)
(global-set-key (kbd "C-2") 'mark-whole-line) ; 2 is near w

その後C-2 C-w、仕事をします。

また、現在の行全体にコメントを付けるなどの作業を簡単にします。


0

これは、itsjeydによる回答の修正版です。これは現在、最も投票数の多い回答であり、私が長年使用した回答です。ただし、問題があります:kill-ring-saveマークが設定されていないため(通常は新しいバッファーに)、アドバイスされたバージョンが失敗することがあります。 。少し掘り下げた後、作業が完了した後にkill-ring-save呼び出しindicate-copied-regionが行われたためにこれが発生することがわかりましたが、ポイントとマークがコピーされた領域と一致しないindicate-copied-regionため、間違った領域をマークしました。

十分に言った。これを解決するソリューションは次のとおりです。

(define-advice kill-ring-save
    (:before-while (beg end &optional region) slick)
  (or mark-active
      (not (called-interactively-p 'interactive))
      (prog1 nil
    (copy-region-as-kill
     (line-beginning-position) (line-beginning-position 2))
    (message "Copied current line"))))

のitsjeydのアドバイスには何の問題もありませんkill-region。とにかく、上記とスタイル的に一貫性のある、それの変形です:

(define-advice kill-region
    (:around (kill-region beg end &optional region) slick)
  (if (or mark-active (not region))
      (funcall kill-region beg end region)
    (funcall kill-region
             (line-beginning-position) (line-beginning-position 2))
    (message "Killed current line")))

あればということtransient-mark-modeになっていない、これらのアドバイスは何もしません。


より包括的なソリューションが必要な場合は、whole-line-or-region代わりにパッケージの使用を検討してください。@sanityincの回答をご覧ください。
ハラルドハンシュオルセン

0

composable.elというパッケージを使用します。パッケージの素晴らしい点は、従来のemacsコマンドを代わりに受け入れるというひねりを加えて、MwとCw(コピーとキルのコマンド)をよりVimのように変更することです。したがってC-w l、行全体を削除します。しかしC-w M->、ファイルの終わりを強制終了するようなこともできます。領域をマークするとき、両方のコマンドは通常のように機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.