it-swarm-tr.com

Emacs'taki bütün bir çizgiyi nasıl kopyalarım?

Bu aynı soruyu VIM için gördüm ve Emacs için nasıl yapılacağını bilmek istediğim bir şeydi. ReSharper'da bu işlem için CTRL-D kullanıyorum. Bunu Emacs'ta gerçekleştirmek için en az komut sayısı kaçtır?

136
Ray Vega

Kullanırım 

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

hangi için yıkar

  • C-a: Satırı başlatmak için imleci hareket ettir
  • C-SPACE: bir seçime başla ("set mark")
  • C-n: imleci bir sonraki satıra taşı
  • M-w: bölgeyi kopyala
  • C-y: yapıştır ("yank")

Adı geçen

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

aynı şeyi tutar (TMTOWTDI)

  • C-a: Satırı başlatmak için imleci hareket ettir
  • C-k: satırı kes ("öldür")
  • C-k: yeni satırı kes
  • C-y: paste ("yank") (ilk kareye döndük)
  • C-y: tekrar yapıştırın (şimdi satırın iki kopyasına sahibiz)

Bunlar, editörünüzdeki C-d ile karşılaştırıldığında utanç verici derecede ayrıntılı, ancak Emacs'ta her zaman bir kişiselleştirme var. C-d, varsayılan olarak delete-char öğesine bağlıdır, peki C-c C-d? Aşağıdakileri .emacs'nuza ekleyin:

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

(@ Nathan'ın elisp sürümü muhtemelen tercih edilir çünkü anahtar bağlantılarından herhangi biri değişirse kırılmaz.)

Dikkat: bazı Emacs modları, başka bir şey yapmak için C-c C-d dosyasını geri alabilir.

135
Chris Conway

Önceki cevaplara ek olarak, bir satırı çoğaltmak için kendi işlevinizi de tanımlayabilirsiniz. Örneğin, aşağıdakileri .emacs dosyanıza koymak, C-d'nin geçerli satırı çoğaltmasını sağlar.

(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)
92
Nate

İmleci çizgiye getirin, başlangıçta değilse CTRL-A, sonra:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

60
epatel

Bir fonksiyonun versiyonunu Nice ile çalışan bir satır çoğaltmak için geri al ve imleç pozisyonunu bozmaz. Bu, Kasım 1997'den itibaren gnu.emacs.sources adresindeki tartışmanın sonucuydu .

(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))

Sonra bu işlevi çağırmak için CTRL-D tanımlayabilirsiniz:

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

kill-line (C-k) yerine C-aC-kC-kC-yC-y yerine, kill-whole-line komutunu kullanın:

C-S-Backspace
C-y
C-y

C-k'ya göre avantajlar, hattın neresinde olduğu önemli değildir (hattın başlangıcını gerektiren C-k'dan farklı olarak) ve ayrıca yeni satırı da öldürür (yine C-k yapmaz).

42
Ray Vega

İşte bunu yapmak için başka bir fonksiyon. Sürümüm öldürme halkasına dokunmuyor ve imleç orijinalin üzerinde bulunduğu yeni satırda sona eriyor. Etkinse (geçici işaret modu) veya aksi takdirde çizgiyi çoğaltmak için varsayılan bölgeyi çoğaltacaktır. Ayrıca önek argümanı verilirse birden fazla kopya çıkarır ve negatif önek argümanı verilirse orijinal satırı yorumlar (eskisini tutarken bir komutun/ifadenin farklı bir sürümünü test etmek için yararlıdır).

(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 'a bağlıyım:

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

Bu, hiçbir zaman bir mod veya başka bir şey tarafından yeniden atanmamalıdır, çünkü C-c ve ardından tek (değiştirilmemiş) bir harf kullanıcı bağları için ayrılmıştır.

24
qmega

Nathan'ın .emacs dosyanıza eklenmesi gereken yoldur ancak değiştirilerek hafifletilebilir 

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

ile

  (newline)

verimli

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

melpa'dan yinelenen bir şey kurun:

M-x paketi-yükleme RET duplicate-şey

ve bu klavyeyi init dosyasına :

(global ayar anahtarı (kbd "M-c") 'yinelenen şey)

5
user2626414

Satır çoğaltmanın başka bir yerde nasıl çalıştığını tam olarak hatırlamıyorum, ancak eski bir SciTE kullanıcısı olarak SciTE-way hakkında bir şeyi sevdim: imleç konumuna dokunmuyor! Yukarıdaki tüm tarifler yeterince iyi değildi benim için, işte benim hippi-sürümü:

(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))))

Sürecinde hiçbir şeyin gerçekten öldürülmediğini, işaretleri ve geçerli seçimlerin bozulmadan kaldığını unutmayın.

BTW, neden bu Nice'n'clean-tüm-çizgi öldürme olayı (C-S-backspace) varken imlecinizi sarhoş etmeye bayılıyorsunuz?

5
mk-fg

Bir anahtara bağlı copy-from-above-command ve bunu kullanın. XEmacs ile sağlandı, ancak GNU Emacs hakkında bilmiyorum.

`copy-from-above-command 'için bir etkileşimli derlenmiş LISP işlevi
- "/usr/share/xemacs/21.4.15/LISP/misc.elc".__ adresinden yüklenmiştir. (komuttan yukarıdan kopyala & isteğe bağlı ARG)

Belgeler: .__ 'dan karakterleri kopyala. önceki satır dışı çizgi , sadece başlangıç. noktanın üstünde. ARG karakterlerini kopyalayın, ancak. bu çizginin sonunu geçmedi. Eğer hayırsa Argüman verilen tüm dinlenme .__ kopyalayın. Hattın Kopyalanan karakterler noktadan önce tamponda eklenir.

4
Darron

çünkü bilmiyorum, bu golf turuna slowball ile başlayacağım:

ctrl-k, y, y

4
Kevin Conner

Son emac'lerde, kopyalamak için satırın herhangi bir yerinde M-w'yi kullanabilirsiniz. Böylece olur:

M-w C-a RET C-y
3
Louis Kottmann
C-a C-k C-k C-y C-y
3
sverrejoh

.emacs içinde sahip olmak isteyebileceğiniz bir şey 

(setq kill-whole-line t)

Temel olarak tüm çizgiyi artı her yeni çizgiyi öldürdüğünüzde (yani C-k aracılığıyla) yeni çizgiyi öldürür. Sonra ekstra kod olmadan, satırı çoğaltmak için C-a C-k C-y C-y'yi yapabilirsiniz. Aşağı yıkar 

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.

Ancak, bunu sık kullanırsanız, belki özel bir anahtar bağlama daha iyi bir fikir olabilir, ancak yalnızca C-a C-k C-y C-y kullanmanın avantajı, çizgiyi geçerli satırın hemen yerine başka bir yere kopyalamanızdır.

3
polyglot

Varsayılanlar bunun için korkunç. Ancak, Emacs'ı SlickEdit ve TextMate gibi çalışacak şekilde genişletebilirsiniz, yani, hiçbir metin seçilmediğinde geçerli satırı kopyala/kes:

(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)))))

Yukarıdakileri .emacs içine yerleştirin. Ardından, bir satırı kopyalamak için M-w. Bir satırı silmek için, C-w. Bir satırı çoğaltmak için C-a M-w C-y C-y C-y ....

3
Marius Andersen

Zaten çok karmaşık çözümler gördüm.

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

Kendi duplicate-line versiyonumu yazdım, çünkü öldürme halkasını mahvetmek istemiyorum.

  (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)
3
Joyer

Avy adlı bir paket var avy-copy-line komutuna sahip. Bu komutu kullandığınızda, pencerenizdeki her satır harf kombinasyonunu alır. O zaman sadece birleşim yazmanız gerekecek ve bu çizgiyi elde edeceksiniz. Bu aynı zamanda bölge için de geçerlidir. O zaman sadece iki kombinasyonu yazmanız gerekir.

Burada arayüzü görebilirsiniz: 

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

3
teksturi

@ [Kevin Conner]: Oldukça yakın, bildiğim kadarıyla. Dikkate alınması gereken diğer tek şey, C-k'ye yeni satırı dahil etmek için kill-whole-line öğesini açmaktır.

2
Allen

İki şey dışında FraGGod'un sürümünü sevdim: (1) Tamponun (interactive "*") ile zaten salt okunur olup olmadığını kontrol etmiyor ve (2) bu son satır boşsa tamponun son satırında başarısız Bu durumda çizgiyi yok edemezsiniz), tamponunuzu salt okunur olarak bırakırsınız.

Bunu çözmek için aşağıdaki değişiklikleri yaptım:

(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)))))
2
phils

Aktif bölge olmadan etkileşimli olarak çağrıldığında, COPY (M-w) yerine tek bir satır:

(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)))))

Aktif bölge olmadan etkileşimli olarak çağrıldığında, KILL (C-w) yerine tek bir satır kullanın.

(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)))))

Ayrıca, ilgili bir notta:

(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)
2
yPhil

Tercihim için bir tane yazarım.

(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)

Ancak, mevcut satır çok baytlık karakterler (örneğin CJK karakterleri) içerdiğinde bunun bir sorun olacağını keşfettim. Bu sorunla karşılaşırsanız, bunun yerine şunu deneyin:

(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)
1
kuanyui

ctrl-kctrl-k, (yeni konuma pozisyon) ctrl-y

Ekle ctrl-a hattın başlangıcında başlamıyorsanız. Ve 2. ctrl-k newline karakterini almaktır. Sadece metni istiyorsanız bu kaldırılabilir.

1
CJP

Bu işlevsellik, hem satır hem de bölge tarafından çoğaltma ve daha sonra nokta ve/veya aktif bölgeyi beklendiği gibi bırakma bakımından JetBrains'in uygulamasıyla eşleşmelidir:

İnteraktif formun etrafına bir sarmalayıcı:

(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)))

Buna kim diyor

(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))

Veya bu

(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))

Ve sonra bu meta + shift + d'ye bağlıyım

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

M-c, Shift+Insertx2 (veya yapıştırma kısayolunuz ne olursa olsun) bunu yapar.

0
Andrew Naguib
;; 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.

inis.el üzerinde yukarıdaki elisp'i ekleyin ve şimdi tüm çizgi fonksiyonunu kesip kopyalayın, sonra bir satırı çoğaltmak için F3 F4'ü kullanabilirsiniz.

0
WisdomFusion

Bu, Chris Conway'in seçtiği cevaba göre daha doğal geliyor.

(genel ayar anahtarı "\ C-c\C-d" "\ C-a\C-\C-n\M\w\C-y\C-p\C-e")

Bu,\C-c\C-d tuş vuruşlarını basitçe tekrarlayarak bir satırı birçok kez çoğaltmanıza olanak tanır.

0
Shim Kporku

İşte mevcut satırı çoğaltmak için bir fonksiyon. Önek bağımsız değişkenleriyle, satırı birkaç kez çoğaltır. Örneğin, C-3 C-S-o geçerli satırı üç kez çoğaltacaktır. Öldürme yüzüğünü değiştirmez. 

(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)
0
Dodgie

Diğer cevaplarda belirtildiği gibi, tuş vuruşlarını LISP koduna bağlamak, bunları başka bir tuş vuruşlarına bağlamaktan daha iyi bir fikirdir. @ Mw'nin cevabı ile kod satırı kopyalar ve işareti yeni satırın sonuna taşır. Bu değişiklik işaret pozisyonunu yeni satırdaki aynı sütunda tutar:

fun duplicate-line ()
  (interactive)
  (let ((col (current-column)))
    (move-beginning-of-line 1)
    (kill-line)
    (yank)
    (newline)
    (yank)
    (move-to-column col)))
0
krsoni

Tüm bu karmaşık çözümlere inanamıyorum. Bu iki tuş vuruşudur:

<C-S-backspace> komutu kill-whole-line komutunu çalıştırır.

C-/ komutu geri al komutunu çalıştırır.

Yani <C-S-backspace> C-/ bütün bir satırı "kopyalamak" için (öldür ve geri al).

Elbette, birden fazla çizgiyi ileri ya da geri öldürmek için bunu sayısal ve negatif argümanlarla birleştirebilirsiniz.

0
Andy

En basit yol Chris Conway'in yöntemidir. 

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

EMACS tarafından zorunlu olan varsayılan yol budur. Bence standardı kullanmak daha iyi. EMACS'ta birinin kendi anahtar bağlayıcı özelliğini özelleştirmeye her zaman dikkat ederim. EMACS zaten yeterince güçlü, bence kendi kilit bağlarına uyum sağlamak için elimizden gelenin en iyisini yapmalıyız. 

Biraz uzun olsa da, buna alıştığınızda hızlı bir şekilde yapabilirsiniz ve bunun eğlenceli olduğunu göreceksiniz!

0
linbianxiaocao

Önek argümanları ve sezgisel davranış nedir (umarım):

(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))))))

İmleç son satırda kalacaktır ... Alternatif olarak, bir sonraki birkaç satırı bir kerede kopyalamak için bir önek belirtmek isteyebilirsiniz:

(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))

Kendimi her iki sıklıkta kullanırken, önek argümanının davranışını değiştirmek için bir sarmalayıcı işlevi kullanarak kendimi buluyorum.

Ve bir bağlama: (global-set-key (kbd "C-S-d") 'duplicate-line)

0
Karthik