it-swarm-eu.dev

Jak mohu duplikovat celou řadu v Emacsu?

Viděl jsem stejnou otázku pro VIM a to bylo něco, co jsem chtěl vědět pro Emacse. V ReSharper používám pro tuto akci CTRL-D. Jaký je nejmenší počet příkazů, které to má provést v Emacsu?

136
Ray Vega

Používám 

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

který se rozpadá na

  • C-a: přesune kurzor na začátek řádku
  • C-SPACE: začátek výběru ("nastavená značka")
  • C-n: přesune kurzor na další řádek
  • M-w: oblast kopírování
  • C-y: vložit ("yank")

Výše uvedené

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

to samé (TMTOWTDI)

  • C-a: přesune kurzor na začátek řádku
  • C-k: řez ("zabít") řádek
  • C-k: řez nového řádku
  • C-y: vložit ("yank") (jsme zpět na čtvereční)
  • C-y: vložit znovu (nyní máme dvě kopie linky)

Oba jsou rozpačitě ostré ve srovnání s C-d ve vašem editoru, ale v Emacsu je vždy přizpůsobení. C-d je ve výchozím nastavení vázáno na delete-char, tak jak je to s C-c C-d? Stačí přidat následující .emacs:

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

(@ Nathanova verze elispu je pravděpodobně vhodnější, protože se neztratí, pokud se změní některá klávesová vazba.)

Dejte si pozor: některé režimy Emacs mohou kultivovat C-c C-d udělat něco jiného.

135
Chris Conway

Kromě předchozích odpovědí můžete také definovat svou vlastní funkci pro kopírování řádku. Například vložením následujícího souboru do souboru .emacs se C-d duplikuje aktuální řádek.

(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

Umístěte kurzor na řádek, pokud ne na začátku a CTRL-A, pak:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

60
epatel

Moje verze funkce duplikovat řádek, který funguje Nice s vrátit zpět a není nepořádek s pozicí kurzoru. Byl výsledkem diskuse v gnu.emacs.sources z listopadu 1997 .

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

Pak můžete definovat CTRL-D pro volání této funkce:

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

Místo kill-line (C-k) jako v C-aC-kC-kC-yC-y použijte příkaz kill-whole-line :

C-S-Backspace
C-y
C-y

Výhody oproti C-k zahrnují, že nezáleží na tom, kde je bod na řádku (na rozdíl od C-k který vyžaduje být na začátku řádku) a také zabíjí nový řádek (opět něco C-k nedělá).

42
Ray Vega

Tady je ještě další funkce, jak to udělat. Moje verze se nedotýká ringu a kurzor končí na novém řádku, kde byl na originálu. Bude duplikovat oblast, pokud je aktivní (režim přechodových značek), nebo výchozí pro kopírování řádků jinak. Bude také dělat více kopií, pokud je dána předpona arg, a komentovat původní řádek, pokud je dána záporná předpona arg (to je užitečné pro testování jiné verze příkazu/příkazu při zachování starého).

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

Mám vázáno na C-c d:

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

Toto by nikdy nemělo být re-přiděleno režimem nebo cokoliv, protože C-c následované jedním (nemodifikovaným) písmenem je vyhrazeno pro uživatelské vazby.

24
qmega

Nathanův přírůstek do vašeho souboru .emacs je způsob, jak jít, ale mohl by být lehce zjednodušen nahrazením 

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

s

  (newline)

poddajný

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

nainstalovat duplikát-věc z melpa:

M-x balíček-instalace RET duplikát-věc

a přidejte tuto klávesovou zkratku do init souboru :

duplicitní věc (globálně nastavený klíč (kbd "M-c"))

5
user2626414

Nepamatuji si, jak funguje duplikace řádků kdekoli jinde, ale jako bývalý uživatel SciTE se mi líbila jedna věc o způsobu SciTE: nedotýká se pozice kurzoru! Takže všechny výše uvedené recepty nebyly dost dobré pro mě, tady je moje hippie verze:

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

Všimněte si, že se nic skutečně nezabije v procesu, takže stopy a aktuální výběr zůstanou nedotčené.

BTW, proč kluci tak rádi trháte kurzorem, když je tu věc Nice'n'clean kill-full-line (C-S-backspace)?

5
mk-fg

Mám copy-from-above-command vázané na klíč a použít. To je poskytováno s XEmacs, ale já nevím o GNU Emacs.

`copy-from-above-command 'je interaktivní kompilovaná funkce LISP
- načteno z "/usr/share/xemacs/21.4.15/LISP/misc.elc" (příkaz copy-from-above-command a nepovinné ARG)

Dokumentace: Zkopírujte znaky z Předchozího neprázdného řádku , začínajícího pouze nad bodem . Zkopírujte znaky ARG, ale Není za koncem tohoto řádku. Není-li uveden žádný argument , Zkopírujte celý zbytek řádku. Zkopírované znaky jsou vloženy do vyrovnávací paměti před bodem.

4
Darron

protože nevím, začnu toto kolo golfu s slowballem:

ctrl-k, y, y

4
Kevin Conner

S nedávnými emacs, můžete použít M-w kdekoli v řádku pro kopírování. Tak se stává:

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

něco, co byste chtěli mít ve svých .emacs je 

(setq kill-whole-line t)

Což v podstatě zabíjí celý řádek plus nový řádek, kdykoliv vyvoláte kill-line (tj. Přes C-k). Pak bez dodatečného kódu stačí udělat C-a C-k C-y C-y pro duplikování řádku. Přeruší se to 

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.

Pokud však toto často používáte, možná by byla lepší myšlenka vyhrazená klávesová vazba, ale výhodou použití C-a C-k C-y C-y je, že můžete duplikovat řádek jinde, místo těsně pod aktuálním řádkem.

3
polyglot

Výchozí hodnoty jsou pro to hrozné. Emacs však můžete rozšířit tak, aby fungoval jako SlickEdit a TextMate, to znamená, že pokud není vybrán žádný text, zkopírujte/ořízněte aktuální řádek:

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

Umístěte výše v .emacs. Potom zkopírujte řádek M-w. Chcete-li odstranit řádek, C-w. Chcete-li duplikovat řádek, C-a M-w C-y C-y C-y ....

3
Marius Andersen

Viděl jsem velmi složitá řešení ...

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

„Napsal jsem vlastní verzi duplicate-line, protože nechci zlikvidovat zabíjecí kruh.

  (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

Existuje balíček nazvaný Avy / Má příkaz avy-copy-line. Když použijete tento příkaz, každý řádek ve vašem okně dostane kombinaci písmen. Pak stačí zadat kombinaci a dostanete tu linku. To platí i pro region. Pak stačí zadat dvě kombinace.

Zde můžete vidět rozhraní: 

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

3
teksturi

@ [Kevin Conner]: Docela blízko, pokud vím. Jediná další věc, kterou je třeba zvážit, je zapnout kill-whole-line a zahrnout do C-k nový řádek.

2
Allen

Líbila se mi verze FraGGodu, kromě dvou věcí: (1) Nezkontroluje, zda je vyrovnávací paměť již jen pro čtení s (interactive "*"), a (2) selže na posledním řádku vyrovnávací paměti, pokud je poslední řádek prázdný (jako v tomto případě nemůžete řádek zabít) a ponechat vyrovnávací paměť jen pro čtení.

Provedl jsem následující změny, abych zjistil, že:

(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

Při interaktivním volání bez aktivní oblasti, COPY (M-w) místo jednoho řádku:

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

Při interaktivním volání s žádnou aktivní oblastí, KILL (C-w) místo jednoho řádku.

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

Také na související poznámce:

(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

Píšu jednu pro mé preference.

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

Ale zjistil jsem, že by to mělo nějaký problém, pokud aktuální řádek obsahuje vícebajtové znaky (např. Znaky CJK). Pokud narazíte na tento problém, zkuste to místo toho:

(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, (poloha do nového umístění) ctrl-y

Přidat ctrl-a pokud nezačínáte na začátku řádku. A druhá ctrl-k je chytit znak nového řádku. To lze odstranit, pokud chcete text.

1
CJP

Tato funkce by se měla shodovat s implementací JetBrains, pokud jde o duplikaci podle čáry nebo oblasti, a poté opustit bod a/nebo aktivní oblast podle očekávání:

Prostě jen obálka kolem interaktivního formuláře:

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

Co to nazývá,

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

Nebo toto

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

A pak jsem to vázal na meta + shift + d

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

M-c, Shift+Insertx2 (nebo co je zkratka pro vložení) to provede.

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.

přidejte elisp nad vámi init.el, a nyní dostanete funkci řez/kopírování celé řádky, pak můžete F3 F4 duplikovat řádek.

0
WisdomFusion

Je to přirozenější s ohledem na vybranou odpověď Chrisa Conwaya.

(globálně nastavený klíč) C-c C-d "" C-c C-n M-w C-y C-e ")

To vám umožňuje duplikovat řádek vícekrát jednoduše opakováním tahů kláves C-c C-d.

0
Shim Kporku

Zde je funkce pro kopírování aktuálního řádku. S argumenty předpony duplikuje řádek několikrát. Například C-3 C-S-o bude duplikovat aktuální řádek třikrát. Nezmění zabíjecí kruh. 

(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

Jak je uvedeno v jiných odpovědích, závazné tahy klíče k kódu LISP jsou lepší nápad, než je vázat na jiné klíčové tahy. S odpovědí @ mw kód duplikuje řádek a přesune značku na konec nového řádku. Tato změna udržuje pozici značky ve stejném sloupci na novém řádku:

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

Nemůžu uvěřit všem těmto komplikovaným řešením. Jedná se o dva stisknutí kláves:

<C-S-backspace> spustí příkaz kill-full-line

C-/ spustí příkaz undo

Takže <C-S-backspace> C-/ "kopírovat" celý řádek (zabít a vrátit zpět).

Můžete to samozřejmě kombinovat s numerickými a negativními argy, abyste zabili více řádků dopředu nebo dozadu.

0
Andy

Nejjednodušší způsob je metoda Chrisa Conwaye. 

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

To je standardní způsob, který nařídil EMACS. Podle mého názoru je lepší použít tento standard. V EMACS jsem vždy opatrný k přizpůsobení vlastního klíče. EMACS je již dostatečně silný, myslím si, že bychom se měli snažit co nejvíce přizpůsobit svým klíčovým vazbám. 

Ačkoli je to trochu zdlouhavé, ale když jste na to zvyklí, můžete to udělat rychle a zjistíte, že je to zábava!

0
linbianxiaocao

S argumenty předpony a tím, co je (doufám) intuitivním chování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))))))

Kurzor zůstane na posledním řádku. Případně můžete zadat předponu pro duplikování několika dalších řádků najednou:

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

Používám obě často, pomocí funkce wrapper přepnout chování předpony argument.

A klíčové spojení: (global-set-key (kbd "C-S-d") 'duplicate-line)

0
Karthik