質問

私が見た VIM についても同じ質問です そしてそれは私自身も Emacs でどのように行うかを知りたかったことでした。ReSharper では、このアクションに CTRL-D を使用します。Emacs でこれを実行するためのコマンドの最小数はいくつですか?

役に立ちましたか?

解決

私が使う

C-a C-SPACE C-n M-w C-y

内訳は

  • C-a:カーソルを行頭に移動
  • C-SPACE:選択範囲を開始します (「マークを設定」)
  • C-n:カーソルを次の行に移動する
  • M-w:領域をコピーする
  • C-y:ペースト (「ヤンク」)

前述の

C-a C-k C-k C-y C-y

同じことになります (TMTOWTDI)

  • C-a:カーソルを行頭に移動
  • C-k:ラインをカット(「キル」)
  • C-k:改行をカットする
  • C-y:ペースト (「ヤンク」) (振り出しに戻ります)
  • C-y:もう一度貼り付けます (行のコピーが 2 つあります)

これらはどちらも、以下に比べて恥ずかしいほど冗長です。 C-d エディタではカスタマイズできますが、Emacs では常にカスタマイズが必要です。 C-d に縛られています delete-char デフォルトではどうですか C-c C-d?以下を追加するだけです .emacs:

(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")

(キーバインドが変更されても壊れないため、@Nathan の elisp バージョンがおそらく推奨されます。)

注意してください:一部の Emacs モードは再利用される可能性があります C-c C-d 何か他のことをするために。

他のヒント

前の回答に加えて、行を複製する独自の関数を定義することもできます。たとえば、.emacs ファイルに次のコードを入力すると、C-d が現在の行を複製します。

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (open-line 1)
  (next-line 1)
  (yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)

カーソルを行に置きます。先頭にない場合は、 CTRL-, 、 それから:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

行を複製する関数の私のバージョンは、元に戻すとうまく機能し、カーソルの位置を混乱させません。それはある結果でした 1997 年 11 月の gnu.emacs.sources での議論.

(defun duplicate-line (arg)
  "Duplicate current line, leaving point in lower line."
  (interactive "*p")

  ;; save the point for undo
  (setq buffer-undo-list (cons (point) buffer-undo-list))

  ;; local variables for start and end of line
  (let ((bol (save-excursion (beginning-of-line) (point)))
        eol)
    (save-excursion

      ;; don't use forward-line for this, because you would have
      ;; to check whether you are at the end of the buffer
      (end-of-line)
      (setq eol (point))

      ;; store the line and disable the recording of undo information
      (let ((line (buffer-substring bol eol))
            (buffer-undo-list t)
            (count arg))
        ;; insert the line arg times
        (while (> count 0)
          (newline)         ;; because there is no newline in 'line'
          (insert line)
          (setq count (1- count)))
        )

      ;; create the undo information
      (setq buffer-undo-list (cons (cons eol (point)) buffer-undo-list)))
    ) ; end-of-let

  ;; put the point in the lowest line and return
  (next-line arg))

次に、CTRL-D を定義してこの関数を呼び出すことができます。

(global-set-key (kbd "C-d") 'duplicate-line)

の代わりに kill-line (C-k)のように C-a C-k C-k C-y C-y 使用 kill-whole-line 指示:

C-S-Backspace
C-y
C-y

以上の利点 C-k (とは異なり、点が線上のどこにあるかは関係ありません) C-k これは行の先頭にある必要があります)、改行も強制終了します(これもまた何かです) C-k しません)。

これを行うためのもう 1 つの関数を次に示します。私のバージョンではキルリングに触れておらず、カーソルはオリジナルの新しい行に移動します。アクティブ (一時マーク モード) の場合は領域が複製され、それ以外の場合はデフォルトで行が複製されます。また、プレフィックス arg が指定されている場合は複数のコピーが作成され、負のプレフィックス arg が指定されている場合は元の行がコメント アウトされます (これは、古いバージョンを保持したまま、別のバージョンのコマンド/ステートメントをテストする場合に便利です)。

(defun duplicate-line-or-region (&optional n)
  "Duplicate current line, or region if active.
With argument N, make N copies.
With negative N, comment out original line and use the absolute value."
  (interactive "*p")
  (let ((use-region (use-region-p)))
    (save-excursion
      (let ((text (if use-region        ;Get region if active, otherwise line
                      (buffer-substring (region-beginning) (region-end))
                    (prog1 (thing-at-point 'line)
                      (end-of-line)
                      (if (< 0 (forward-line 1)) ;Go to beginning of next line, or make a new one
                          (newline))))))
        (dotimes (i (abs (or n 1)))     ;Insert N times, or once if not specified
          (insert text))))
    (if use-region nil                  ;Only if we're working with a line (not a region)
      (let ((pos (- (point) (line-beginning-position)))) ;Save column
        (if (> 0 n)                             ;Comment out original with negative arg
            (comment-region (line-beginning-position) (line-end-position)))
        (forward-line 1)
        (forward-char pos)))))

私はそれに縛られています C-c d:

(global-set-key [?\C-c ?d] 'duplicate-line-or-region)

これはモードなどによって決して再割り当てされるべきではありません。 C-c その後に続く 1 つの (変更されていない) 文字は、ユーザー バインディング用に予約されています。

Nathan を .emacs ファイルに追加するのが最善の方法ですが、次のように置き換えることで少し簡素化できます。

  (open-line 1)
  (next-line 1)

  (newline)

譲る

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (newline)
  (yank)
)
(global-set-key (kbd "C-d") 'duplicate-line)

他の場所で行の複製がどのように機能するのかよく覚えていませんが、元 SciTE ユーザーとして、SciTE-way で気に入った点が 1 つあります。カーソル位置に触れません!したがって、上記のレシピはすべて私にとって十分ではありませんでした。これが私のヒッピーバージョンです。

(defun duplicate-line ()
    "Clone line at cursor, leaving the latter intact."
    (interactive)
    (save-excursion
        (let ((kill-read-only-ok t) deactivate-mark)
            (toggle-read-only 1)
            (kill-whole-line)
            (toggle-read-only 0)
            (yank))))

実際にはプロセス中に何も強制終了されず、マークと現在の選択はそのまま残ることに注意してください。

ところで、なぜ皆さんは、このきれいな全行キル機能 (C-S-バックスペース) があるときにカーソルを動かすのがそんなに好きなのでしょうか?

メルパから重複したものをインストールします。

M-x パッケージインストール RET の重複したもの

このキーバインドを追加します 初期化ファイル :

(グローバルセットキー (kbd "M-c") '重複するもの)

分からないので、今回のゴルフラウンドはスローボールで始めます。

Ctrl+K、Y、Y

' 私は自分のバージョンを書きました duplicate-line, だって、殺人リングを台無しにしたくないから。

  (defun jr-duplicate-line ()
    "EASY"
    (interactive)
    (save-excursion
      (let ((line-text (buffer-substring-no-properties
                        (line-beginning-position)
                        (line-end-position))))
        (move-end-of-line 1)
        (newline)
        (insert line-text))))
  (global-set-key "\C-cd" 'jr-duplicate-line)

私は持っている copy-from-above-command キーにバインドしてそれを使用します。XEmacs には付属していますが、GNU Emacs については知りません。

「コピー-From-Above-Command」は、インタラクティブなコンパイルされたLISP関数です
- "/usr/share/xemacs/21.4.15/lisp/misc.elc"からロード

ドキュメンテーション: 以前の非ブランクラインから文字をコピーします, 、ポイントのすぐ上。arg文字をコピーしますが、その行の終わりを過ぎてはなりません。引数が与えられていない場合は、行の残りの部分をコピーします。コピーされた文字は、ポイントの前にバッファーに挿入されます。

C-a C-k C-k C-y C-y

.emacs に含めておきたいものは次のとおりです。

(setq kill-whole-line t)

これは基本的に、kill-lineを呼び出すたびに行全体と改行を強制終了します(つまり、C-k経由)。その後、追加のコードを使用せずに、C-a C-k C-y C-y を実行するだけで行を複製できます。それは次のようになります

C-a go to beginning of line
C-k kill-line (i.e. cut the line into clipboard)
C-y yank (i.e. paste); the first time you get the killed line back; 
    second time gives the duplicated line.

ただし、これを頻繁に使用する場合は、専用のキー バインドを使用する方が良いアイデアかもしれません。ただし、C-a C-k C-y C-y を使用する利点は、現在の行のすぐ下ではなく、別の場所に行を複製できることです。

これに関してデフォルトはひどいです。ただし、Emacs を拡張して SlickEdit や TextMate のように機能させることもできます。つまり、テキストが選択されていないときに現在の行をコピー/カットすることができます。

(transient-mark-mode t)
(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)))))
(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)))))

上記を入れます .emacs. 。次に、行をコピーするには、 M-w. 。行を削除するには、 C-w. 。行を複製するには、 C-a M-w C-y C-y C-y ....

私は FraGGod のバージョンが気に入りましたが、次の 2 つの点が異なります。(1) バッファがすでに読み取り専用であるかどうかはチェックしません。 (interactive "*"), (2) バッファの最後の行が空の場合はその行で失敗し (その場合は行を強制終了できないため)、バッファは読み取り専用のままになります。

それを解決するために次の変更を加えました。

(defun duplicate-line ()
  "Clone line at cursor, leaving the latter intact."
  (interactive "*")
  (save-excursion
    ;; The last line of the buffer cannot be killed
    ;; if it is empty. Instead, simply add a new line.
    (if (and (eobp) (bolp))
        (newline)
      ;; Otherwise kill the whole line, and yank it back.
      (let ((kill-read-only-ok t)
            deactivate-mark)
        (toggle-read-only 1)
        (kill-whole-line)
        (toggle-read-only 0)
        (yank)))))

最近の emacs では、行のどこでも M-w を使用してコピーできます。したがって、次のようになります。

M-w C-a RET C-y

とにかく、非常に複雑な解決策を目にしました...

(defun duplicate-line ()
  "Duplicate current line"
  (interactive)
  (kill-whole-line)
  (yank)
  (yank))
(global-set-key (kbd "C-x M-d") 'duplicate-line)

というパッケージがあります アヴィ avy-copy-line コマンドがあります。このコマンドを使用すると、ウィンドウ内のすべての行に文字の組み合わせが取得されます。次に、「combination」と入力するだけで、その行が表示されます。これは地域にも当てはまります。あとは 2 つの組み合わせを入力するだけです。

ここにインターフェースが表示されます。

http://i68.tinypic.com/24fk5eu.png

@[ケビン・コナー]:私の知る限り、かなり近いです。他に考慮すべき唯一のことは、オンにすることです kill-whole-line C-k に改行を含めます。

アクティブな領域を持たずに対話的に呼び出された場合は、代わりに 1 行を COPY (M-w) します。

(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 行を KILL (C-w) します。

(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))
     (message "Killed line")
     (list (line-beginning-position)
           (line-beginning-position 2)))))

また、関連するメモとして:

(defun move-line-up ()
  "Move up the current line."
  (interactive)
  (transpose-lines 1)
  (forward-line -2)
  (indent-according-to-mode))

(defun move-line-down ()
  "Move down the current line."
  (interactive)
  (forward-line 1)
  (transpose-lines 1)
  (forward-line -1)
  (indent-according-to-mode))

(global-set-key [(meta shift up)]  'move-line-up)
(global-set-key [(meta shift down)]  'move-line-down)

Ctrl-k, Ctrl-k, (新しい場所への位置) Ctrl-y

追加 Ctrl-ある 行の先頭から始めない場合。そして2番目 Ctrl-k 改行文字を取得することです。テキストのみが必要な場合は削除できます。

自分の好みで書きます。

(defun duplicate-line ()
  "Duplicate current line."
  (interactive)
  (let ((text (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
        (cur-col (current-column)))
    (end-of-line) (insert "\n" text)
    (beginning-of-line) (right-char cur-col)))
(global-set-key (kbd "C-c d l") 'duplicate-line)

しかし、現在の行にマルチバイト文字が含まれている場合(例:CJK の文字)。この問題が発生した場合は、代わりに次のことを試してください。

(defun duplicate-line ()
  "Duplicate current line."
  (interactive)
  (let* ((text (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
         (cur-col (length (buffer-substring-no-properties (point-at-bol) (point)))))
    (end-of-line) (insert "\n" text)
    (beginning-of-line) (right-char cur-col)))
(global-set-key (kbd "C-c d l") 'duplicate-line)

この機能は、ラインまたは領域の両方で複製し、ポイントおよび/またはアクティブな領域を期待どおりに残すという点で、JetBrains の実装と一致する必要があります。

インタラクティブなフォームを囲む単なるラッパーです。

(defun wrx/duplicate-line-or-region (beg end)
  "Implements functionality of JetBrains' `Command-d' shortcut for `duplicate-line'.
   BEG & END correspond point & mark, smaller first
   `use-region-p' explained: 
   http://emacs.stackexchange.com/questions/12334/elisp-for-applying-command-to-only-the-selected-region#answer-12335"
  (interactive "r")
  (if (use-region-p)
      (wrx/duplicate-region-in-buffer beg end)
    (wrx/duplicate-line-in-buffer)))

これを呼び出すと、

(defun wrx/duplicate-region-in-buffer (beg end)
  "copy and duplicate context of current active region
   |------------------------+----------------------------|
   |        before          |           after            |
   |------------------------+----------------------------|
   | first <MARK>line here  | first line here            |
   | second item<POINT> now | second item<MARK>line here |
   |                        | second item<POINT> now     |
   |------------------------+----------------------------|
   TODO: Acts funky when point < mark"
  (set-mark-command nil)
  (insert (buffer-substring beg end))
  (setq deactivate-mark nil))

あるいはこれ

(defun wrx/duplicate-line-in-buffer ()
  "Duplicate current line, maintaining column position.
   |--------------------------+--------------------------|
   |          before          |          after           |
   |--------------------------+--------------------------|
   | lorem ipsum<POINT> dolor | lorem ipsum dolor        |
   |                          | lorem ipsum<POINT> dolor |
   |--------------------------+--------------------------|
   TODO: Save history for `Cmd-Z'
   Context: 
   http://stackoverflow.com/questions/88399/how-do-i-duplicate-a-whole-line-in-emacs#answer-551053"
  (setq columns-over (current-column))
  (save-excursion
    (kill-whole-line)
    (yank)
    (yank))
  (let (v)
    (dotimes (n columns-over v)
      (right-char)
      (setq v (cons n v))))
  (next-line))

そして、これをmeta+shift+dにバインドします

(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)

接頭辞引数を使用した場合、および (私が望んでいる) 直感的な動作は次のとおりです。

(defun duplicate-line (&optional arg)
  "Duplicate it. With prefix ARG, duplicate ARG times."
  (interactive "p")
  (next-line 
   (save-excursion 
     (let ((beg (line-beginning-position))
           (end (line-end-position)))
       (copy-region-as-kill beg end)
       (dotimes (num arg arg)
         (end-of-line) (newline)
         (yank))))))

カーソルは最後の行に残ります。あるいは、接頭辞を指定して、次の数行を一度に複製することもできます。

(defun duplicate-line (&optional arg)
  "Duplicate it. With prefix ARG, duplicate ARG times."
  (interactive "p")
  (save-excursion 
    (let ((beg (line-beginning-position))
          (end 
           (progn (forward-line (1- arg)) (line-end-position))))
      (copy-region-as-kill beg end)
      (end-of-line) (newline)
      (yank)))
  (next-line arg))

私は両方を頻繁に使用しており、ラッパー関数を使用して接頭辞引数の動作を切り替えています。

そしてキーバインド:(global-set-key (kbd "C-S-d") 'duplicate-line)

;; http://www.emacswiki.org/emacs/WholeLineOrRegion#toc2
;; cut, copy, yank
(defadvice kill-ring-save (around slick-copy activate)
  "When called interactively with no active region, copy a single line instead."
  (if (or (use-region-p) (not (called-interactively-p)))
      ad-do-it
    (kill-new (buffer-substring (line-beginning-position)
                                (line-beginning-position 2))
              nil '(yank-line))
    (message "Copied line")))
(defadvice kill-region (around slick-copy activate)
  "When called interactively with no active region, kill a single line instead."
  (if (or (use-region-p) (not (called-interactively-p)))
      ad-do-it
    (kill-new (filter-buffer-substring (line-beginning-position)
                                       (line-beginning-position 2) t)
              nil '(yank-line))))
(defun yank-line (string)
  "Insert STRING above the current line."
  (beginning-of-line)
  (unless (= (elt string (1- (length string))) ?\n)
    (save-excursion (insert "\n")))
  (insert string))

(global-set-key (kbd "<f2>") 'kill-region)    ; cut.
(global-set-key (kbd "<f3>") 'kill-ring-save) ; copy.
(global-set-key (kbd "<f4>") 'yank)           ; paste.

上記の elisp を init.el に追加すると、行全体のカット/コピー機能が得られ、F3 F4 で行を複製できます。

最も簡単な方法は Chris Conway の方法です。

C-a C-SPACE C-n M-w C-y

これは EMACS によって義務付けられたデフォルトの方法です。私の意見では、標準を使用する方が良いと思います。私は EMACS で独自のキーバインディングをカスタマイズすることに常に注意を払っています。EMACS はすでに十分強力なので、独自のキー バインディングに適応するために最善を尽くす必要があると思います。

少し長いですが、慣れれば早くできるので楽しいですよ!

現在の行を複製する関数です。接頭辞引数を使用すると、行が複数回複製されます。例えば。、 C-3 C-S-o 現在の行を 3 回複製します。キルリングは変わらない。

(defun duplicate-lines (arg)
  (interactive "P")
  (let* ((arg (if arg arg 1))
         (beg (save-excursion (beginning-of-line) (point)))
         (end (save-excursion (end-of-line) (point)))
         (line (buffer-substring-no-properties beg end)))
    (save-excursion
      (end-of-line)
      (open-line arg)
      (setq num 0)
      (while (< num arg)
        (setq num (1+ num))
        (forward-line 1)
        (insert-string line))
      )))

(global-set-key (kbd "C-S-o") 'duplicate-lines)

私はこれらすべての複雑な解決策が信じられません。これは 2 つのキーストロークです。

<C-S-backspace> コマンド kill-whole-line を実行します

C-/ undoコマンドを実行します

それで <C-S-backspace> C-/ 行全体を「コピー」します (強制終了して元に戻します)。

もちろん、これを数値および負の引数と組み合わせて、前方または後方の複数行を強制終了することができます。

Chris Conway が選択した回答に関しては、これがより自然に感じられます。

(グローバルセットキー "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y\C-p\C-e")

これにより、\C-c\C-d キー ストロークを繰り返すだけで、行を複数回複製できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top