Làm cách nào để sao chép toàn bộ một dòng trong Emacs?


155

Tôi đã thấy câu hỏi tương tự cho VIM và đó là điều mà bản thân tôi muốn biết làm thế nào cho Emacs. Trong ReSharper tôi sử dụng CTRL-D cho hành động này. Số lượng lệnh ít nhất để thực hiện điều này trong Emacs là gì?


2
Tất nhiên, đó là emacs nên TMTOWTDI - có 22! (và đang tính) c2.com/cgi/wiki?ThereIsMoreThanOneWayToDoIt
Tom

Câu trả lời:


150

tôi sử dụng

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

mà phá vỡ

  • C-a: di chuyển con trỏ đến đầu dòng
  • C-SPACE: bắt đầu lựa chọn ("đặt dấu")
  • C-n: di chuyển con trỏ đến dòng tiếp theo
  • M-w: vùng sao chép
  • C-y: dán ("yank")

Đã nói ở trên

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

số tiền cho cùng một điều (TMTOWTDI)

  • C-a: di chuyển con trỏ đến đầu dòng
  • C-k: cắt ("giết") dòng
  • C-k: cắt dòng mới
  • C-y: paste ("yank") (chúng tôi quay lại hình vuông)
  • C-y: dán lại (bây giờ chúng tôi đã có hai bản sao của dòng)

Cả hai đều dài dòng đáng xấu hổ so với C-dtrong trình soạn thảo của bạn, nhưng trong Emacs luôn có một tùy chỉnh. C-dbị ràng buộc delete-chartheo mặc định, vậy làm thế nào C-c C-d? Chỉ cần thêm các mục sau vào .emacs:

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

(Phiên bản elisp của @ Nathan có lẽ thích hợp hơn, vì nó sẽ không bị hỏng nếu bất kỳ ràng buộc chính nào bị thay đổi.)

Coi chừng: một số chế độ Emacs có thể lấy lại C-c C-dđể làm việc khác.


5
Chào! Xin lưu ý rằng nếu bạn có '(setq kill-all-line t)', bạn sẽ chỉ cần một 'Ck' (giải pháp 2) vì nó đã giết dòng mới cùng với nội dung của dòng. Tôi thích sử dụng 'C-k'. Chúc mừng, Daniel
danielpoe 16/2/2016

179
Điều này thực sự là xấu hổ.
tofutim

18
Thế còn C-S-backspace C-y C-y?
ericzma

1
Mw là gì sử dụng chìa khóa nào cho việc đó?
Bala

4
@Bala "M" là "Meta" (thường là Esc hoặc Alt, nó phụ thuộc vào bố cục bàn phím của bạn). "Mw" là "Meta" và "w" đồng thời (trên bàn phím của tôi, "Alt-w").
Chris Conway

96

Ngoài các câu trả lời trước, bạn cũng có thể xác định chức năng của riêng mình để nhân đôi một dòng. Ví dụ: đặt phần sau vào tệp .emacs của bạn sẽ khiến Cd nhân đôi dòng hiện tại.

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

Tôi nhận được lỗi sau với điều này:Symbol's function definition is void: move-beginning-of-line
Rohaq

5
Vấn đề với điều này là khóa "Del" cũng bị ràng buộc để sao chép dòng ...
David Gomes

Vì vậy, bất kỳ ý tưởng làm thế nào để bỏ ràng buộc Deltừ chức năng này?
Alexander Shcheblikin

OK, tìm thấy một giải pháp để trở Dellại bình thường trong khi vẫn giữ nguyên cái mới C-d: (global-set-key (kbd "<delete>") 'delete-char)cần được thêm vào sau C-dđịnh nghĩa.
Alexander Shcheblikin

Thử làm điều đó trên một dòng trống dẫn đến việc chèn hai dòng, thay vì chỉ một. Tôi không biết tại sao. Có một sửa chữa dễ dàng?
Zelphir Kaltstahl

68

Đặt con trỏ trên dòng, nếu không bắt đầu, hãy làm CTRL- A, sau đó:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y


Tôi không nghĩ CY thứ hai là cần thiết.
Bastien Léonard

4
nó sẽ không phải là một bản sao mà không có
epatel

17
Sử dụng CS-Backspace (kill-line-line) thay vì Ck. Bạn không cần phải xoay với vị trí con trỏ hoặc giết dòng mới.
Nietzche-jou

Điều này hoạt động độc đáo nhưng không có cách nào ngắn để làm điều này?
Stryker

52

Phiên bản của tôi về chức năng sao chép một dòng hoạt động tốt với hoàn tác và không gây rối với vị trí con trỏ. Đó là kết quả của một cuộc thảo luận trong gnu.emacs.source từ tháng 11 năm 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))

Sau đó, bạn có thể xác định CTRL-D để gọi hàm này:

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

Thông minh! Tính năng hoàn tác và vị trí con trỏ làm cho cái này tốt nhất. Cảm ơn!
ptrn

Ngoài ra, trên liên kết cũng có một số mã cho các khu vực!
pcarvalho

Giải pháp rất hay. Thx
Plankalkül

Công trình tuyệt vời. Cảm ơn giải pháp.
Stryker

@pesche crux-duplicate-current-line-or-regionhoạt động tốt hơn đối với tôi, bởi vì với chức năng của bạn, nó hoàn tác sao chép dòng và hoạt động cuối cùng.
rofrol

47

Thay vì kill-line( C-k) như trong C-a C-k C-k C-y C-y sử dụng kill-whole-linelệnh:

C-S-Backspace
C-y
C-y

Những lợi thế C-kbao gồm không quan trọng điểm nằm ở đâu trên đường thẳng (không giống như C-kđiểm bắt đầu của dòng) và nó cũng giết chết dòng mới (một lần nữa điều gì đó C-kkhông làm được).


2
Kudos @RayVega! Tôi đã thử giải pháp này và nó hoạt động như một nhà vô địch (dù sao trong GNU Emacs 23.3.1 của tôi). Là giải pháp này không làm việc cho một số người? Đây là câu trả lời tốt nhất cho câu hỏi (của riêng bạn).
JS.

1
Bạn nên chấp nhận câu trả lời này là câu trả lời đúng. Nó thực hiện chính xác những gì bạn yêu cầu và trong "số lượng lệnh ít nhất".
Davor Cubranic

24

Đây là một chức năng khác để làm điều này. Phiên bản của tôi không chạm vào vòng khử và con trỏ kết thúc trên dòng mới, nơi nó ở trên bản gốc. Nó sẽ nhân đôi vùng nếu nó hoạt động (chế độ đánh dấu thoáng qua) hoặc mặc định để sao chép dòng khác. Nó cũng sẽ tạo nhiều bản sao nếu được cung cấp tiền tố arg và nhận xét dòng gốc nếu được cung cấp tiền tố phủ định arg (điều này hữu ích để kiểm tra phiên bản khác của lệnh / câu lệnh trong khi vẫn giữ nguyên phiên bản cũ).

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

Tôi có nó ràng buộc với C-c d:

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

Điều này không bao giờ được gán lại bởi một chế độ hoặc bất cứ điều gì vì C-ctheo sau là một chữ cái duy nhất (chưa sửa đổi) được dành riêng cho các ràng buộc người dùng.


Giải pháp tốt nhất cho đến nay
Leo Ufimtsev

1
Tôi đặt nó trong tập tin .emacs của tôi, nhưng khi tôi cố gắng sử dụng thì C-c dtôi gặp lỗi command-execute: Wrong type argument: commandp, duplicate-line-or-region. Có ý kiến ​​gì không? Tôi đang sử dụng Emacs 25.1.1 trên Windows
Junius

Giải pháp thực sự tốt đẹp, tôi đánh giá cao tính năng vùng và tính năng bình luận với tiêu cực. Cũng giống như các ràng buộc quan trọng đề nghị.
Alex Trueman

18

Sự bổ sung của Nathan vào tệp .emacs của bạn là cách để đi nhưng nó có thể được đơn giản hóa một chút bằng cách thay thế

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

với

  (newline)

năng suất

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

Cái này đẹp đấy. Cảm ơn!
tejasbubane

7

cài đặt trùng lặp từ melpa:

Mx gói cài đặt RET trùng lặp

và thêm keybinding này vào tệp init :

(key-set-key (kbd "Mc") 'trùng lặp)


Hình như không có ở đó vào ngày này.
MarkSkayff

5

Tôi không nhớ cách sao chép dòng hoạt động ở bất cứ nơi nào khác, nhưng với tư cách là một người dùng SciTE trước đây, tôi thích một điều về SciTE-way: nó không chạm vào vị trí con trỏ! Vì vậy, tất cả những người nhận ở trên không đủ tốt cho tôi, đây là phiên bản hippie của tôi:

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

Lưu ý rằng không có gì thực sự bị giết trong quá trình, giữ nguyên dấu và lựa chọn hiện tại.

BTW, tại sao các bạn lại thích giật con trỏ xung quanh khi có thứ giết người toàn diện đẹp đẽ này (CS-backspace)?


4

bởi vì tôi không biết, tôi sẽ bắt đầu vòng golf này bằng một quả bóng chậm:

ctrl-k, y, y


4

một cái gì đó bạn có thể muốn có trong .emacs của bạn là

(setq kill-whole-line t)

Về cơ bản sẽ giết chết toàn bộ dòng cộng với dòng mới bất cứ khi nào bạn gọi kill-line (tức là thông qua Ck). Sau đó, không cần thêm mã, bạn chỉ có thể thực hiện Ca Ck Cy Cy để nhân đôi dòng. Nó bị hỏng

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.

Nhưng nếu bạn sử dụng điều này thường xuyên thì có lẽ một ràng buộc khóa chuyên dụng có thể là một ý tưởng tốt hơn, nhưng lợi thế của việc chỉ sử dụng Ca Ck Cy Cy là bạn có thể sao chép dòng ở nơi khác, thay vì ngay dưới dòng hiện tại.


4

Tôi đã copy-from-above-commandràng buộc với một chìa khóa và sử dụng đó. Nó được cung cấp với XEmac, nhưng tôi không biết về GNU Emacs.

`copy-from-trên-lệnh 'là một hàm Lisp được biên dịch tương tác
- được tải từ" /usr/share/xemacs/21.4.15/lisp/misc.elc "(copy-from-trên-lệnh & ARG tùy chọn)

Tài liệu: Sao chép các ký tự từ dòng không trống trước đó , bắt đầu ngay trên điểm. Sao chép các ký tự ARG, nhưng không qua cuối dòng đó. Nếu không có đối số được đưa ra, sao chép toàn bộ phần còn lại của dòng. Các ký tự được sao chép được chèn vào bộ đệm trước điểm.


Đối với phiên bản 23, đây cũng là một phần của bản phân phối GNU Emacs tiêu chuẩn.
viam0Zah

Nó dường như không có trong phiên bản của tôi. Có cái gì phải được tải? Phiên bản của tôi là GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped].
qmega

2
@qmega Bạn cần làm (yêu cầu 'misc).
Dmitry

4

Có gói có tên Avy Nó có lệnh avy-copy-line. Khi bạn sử dụng lệnh đó, mọi dòng trong cửa sổ của bạn sẽ được kết hợp chữ cái. Sau đó, bạn chỉ cần gõ kết hợp và bạn nhận được dòng đó. Điều này cũng hoạt động cho khu vực. Sau đó, bạn chỉ cần gõ hai kết hợp.

Tại đây bạn có thể thấy giao diện:

nhập mô tả hình ảnh ở đây



3

Mặc định là khủng khiếp cho điều này. Tuy nhiên, bạn có thể mở rộng Emacs để hoạt động như SlickEdit và TextMate, nghĩa là sao chép / cắt dòng hiện tại khi không có văn bản nào được chọn:

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

Đặt ở trên .emacs. Sau đó, để sao chép một dòng , M-w. Để xóa một dòng , C-w. Để nhân đôi một dòng , C-a M-w C-y C-y C-y ....


3

'Tôi đã viết phiên bản của riêng mình duplicate-line, vì tôi không muốn làm hỏng vòng giết chóc.

  (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

Tôi thích phiên bản của FraGGod, ngoại trừ hai điều: (1) Nó không kiểm tra xem bộ đệm đã chỉ đọc với chưa (interactive "*")và (2) nó không thành công ở dòng cuối cùng của bộ đệm nếu dòng cuối cùng trống (như bạn không thể tắt dòng trong trường hợp đó), để bộ đệm của bạn chỉ đọc.

Tôi đã thực hiện các thay đổi sau để giải quyết rằng:

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

3

Với các emacs gần đây, bạn có thể sử dụng Mw ở bất cứ đâu trong dòng để sao chép nó. Vì vậy, nó trở thành:

M-w C-a RET C-y

Có thật không? Emacs "gần đây" sẽ là gì? Không phải trường hợp nào với 24.4: bạn nhận được "Dấu hiện chưa được đặt, vì vậy không có khu vực."
Davor Cubranic

Emacs hiện tại là 24,5 và M-wbị ràng buộc easy-kill. Kiểm tra xem đó là những gì bạn nhận được khi làmC-h c M-w
Louis Kottmann

Không hoạt động trong Emacs 24.5.1. Chỉ được sao chép từ đầu dòng đến điểm ở đầu cùng một dòng sau khi chèn một dòng trống trước đó.
Derek Mahar

3

Dù sao thì tôi cũng thấy những giải pháp rất phức tạp ...

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

Lưu ý rằng điều này sẽ gây rối với vòng giết.
Dodgie

Điều này nối thêm dòng vào chính nó khi nó là dòng cuối cùng và tệp không kết thúc trong một dòng mới
Đánh dấu

2

@ [Kevin Conner]: Khá gần, theo như tôi biết. Điều khác duy nhất để xem xét là bật kill-whole-lineđể bao gồm dòng mới trong Ck.


@ ALLen: xóa []trong@[Kevin Conner]
jfs

2

ctrl- k, ctrl- k, (vị trí đến vị trí mới) ctrl-y

Thêm một ctrl- anếu bạn không bắt đầu ở đầu dòng. Và thứ 2 ctrl- klà lấy nhân vật dòng mới. Nó có thể được gỡ bỏ nếu bạn chỉ muốn văn bản.


Đây phải là phương pháp đơn giản nhất ở đây. Cảm ơn!
bartlomiej.n

2

Khi được gọi tương tác không có vùng hoạt động, thay vào đó, COPY (Mw) một dòng duy nhấ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)))))

Khi được gọi tương tác không có vùng hoạt động, thay vào đó, KILL (Cw) một dòng duy nhất.

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

Ngoài ra, trên một lưu ý liên quan:

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

1

Tôi viết một cho sở thích của tôi.

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

Nhưng tôi thấy điều này sẽ có một số vấn đề khi dòng hiện tại chứa các ký tự nhiều byte (ví dụ: các ký tự CJK). Nếu bạn gặp phải vấn đề này, hãy thử điều này thay vào đó:

(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

Chức năng này phải phù hợp với triển khai của JetBrains về mặt sao chép cả theo dòng hoặc khu vực, sau đó để lại điểm và / hoặc khu vực hoạt động như mong đợi:

Chỉ là một trình bao bọc xung quanh các hình thức tương tá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)))

Cái này gọi là

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

Hoặc cái này

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

Và sau đó tôi có ràng buộc này với meta + shift + d

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

1

Như đã đề cập trong các câu trả lời khác, ràng buộc các nét chính với mã lisp là một ý tưởng tốt hơn so với ràng buộc chúng với các nét chính khác. Với câu trả lời của @ mw, mã sẽ nhân đôi dòng và di chuyển dấu đến cuối dòng mới. Sửa đổi này giữ vị trí đánh dấu ở cùng một cột trên dòng mới:

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

1

Nếu bạn đang sử dụng Spacemac, bạn chỉ cần sử dụng duplicate-line-or-region, ràng buộc với:

SPC x l d 

0

Với các đối số tiền tố và hành vi trực quan (tôi hy vọng) là gì:

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

Con trỏ sẽ vẫn ở dòng cuối cùng. Ngoài ra, bạn có thể muốn chỉ định một tiền tố để nhân đôi một vài dòng tiếp theo cùng một lúc:

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

Tôi thấy mình sử dụng cả hai thường xuyên, sử dụng hàm bao bọc để chuyển đổi hành vi của đối số tiền tố.

Và một phím bấm: (global-set-key (kbd "C-S-d") 'duplicate-line)


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

thêm elisp ở trên cho bạn init.el và bạn có chức năng cắt / sao chép toàn bộ dòng ngay bây giờ, sau đó bạn có thể F3 F4 để nhân đôi một dòng.


0

Cách đơn giản nhất là phương pháp của Chris Conway.

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

Đó là cách mặc định được ủy quyền bởi EMACS. Theo tôi, tốt hơn là sử dụng tiêu chuẩn. Tôi luôn cẩn thận đối với việc tùy chỉnh ràng buộc khóa của chính mình trong EMACS. EMACS đã đủ mạnh, tôi nghĩ chúng ta nên cố gắng hết sức để thích nghi với các ràng buộc chính của nó.

Mặc dù nó hơi dài, nhưng khi bạn đã quen với nó, bạn có thể làm nhanh và sẽ thấy điều này thật thú vị!


4
Tất cả mọi thứ được xem xét, Emacs bắt buộc rất ít - chiến thắng lớn mà nó mang lại cho bạn là dễ dàng tùy chỉnh nó theo nhu cầu của riêng bạn. Tất nhiên trong thực tế có rất nhiều cách tiêu chuẩn làm việc mà nó có lợi cho dính vào, nhưng nếu bạn đang sử dụng "mặc định" Emacs và làm điều gì đó một cách khó khăn hơn hơn mức cần thiết chỉ vì bạn nghĩ rằng "nó tốt hơn để sử dụng tiêu chuẩn" , bạn đang làm sai rất nhiều.
phils

0

Đây là một chức năng để nhân đôi dòng hiện tại. Với các đối số tiền tố, nó sẽ nhân đôi dòng nhiều lần. Ví dụ, C-3 C-S-osẽ nhân đôi dòng hiện tại ba lần. Không thay đổi vòng giết.

(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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.