Как мне продублировать целую строку в Emacs?

Я видел этот же вопрос для VIM, и я сам хотел знать, как это сделать для Emacs. В ReSharper я использую CTRL-D для этого действия. Какое наименьшее количество команд для выполнения этого в Emacs?

Конечно, это emacs, так что TMTOWTDI - там 22! (и считает) c2.com/cgi/wiki?ThereIsMoreThanOneWayToDoIt

Tom 21.05.2014 06:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
162
1
74 737
35
Перейти к ответу Данный вопрос помечен как решенный

Ответы 35

ну я обычно использовал:

Ctl-Space (set the mark)
move to end of line
Ctl-K kill line
Ctl-Y * 2 (yank the line back)

может быть гораздо лучший способ: P

Вы имеете в виду: C-a C-SPC C-e M-w RET C-y?

jfs 18.09.2008 05:37

да :) именно так хе-хе.

Arthur Thomas 19.09.2008 21:03

@Aurthor Thomas: Зачем убивать? Почему бы просто не скопировать?

viam0Zah 10.08.2010 11:08

Артур Томас, это пишется прямо здесь! ха-ха. Ctl-W тоже в порядке. Он просто спрашивал об одной строчке. Вау.

Arthur Thomas 12.08.2010 01:04

потому что я не знаю, я начну этот раунд гольфа с медленного мяча:

ctrl-k, y, y

ctrl-k, ctrl-k, (позиция в новое место) ctrl-y

Добавьте ctrl-a, если вы не начинаете с начала строки. А второй ctrl-k должен захватить символ новой строки. Его можно удалить, если вам просто нужен текст.

Это должен быть самый простой метод. Спасибо!

bartlomiej.n 28.07.2018 18:58

Поместите курсор в строку, если не в начале, сделайте CTRL-A, затем:

CTRL-K

CTRL-K

CTRL-Y

CTRL-Y

Не думаю, что нужен второй CY.

Bastien Léonard 16.06.2009 01:35

не будет дубликата без

epatel 16.06.2009 02:23

Используйте C-S-Backspace (kill-all-line) вместо C-k. Вам не нужно винить положение курсора или убивать новую строку.

Nietzche-jou 16.06.2009 09:15

Это прекрасно работает, но разве нет короткого способа сделать это?

Stryker 05.08.2017 04:45

@ [Кевин Коннер]: Насколько я знаю, довольно близко. Единственное, что нужно учитывать, - это включить kill-whole-line, чтобы включить новую строку в C-k.

@Allen: удалите [ и ] в @[Kevin Conner]

jfs 18.09.2008 05:32

C-a C-k C-k C-y C-y
Ответ принят как подходящий

я использую

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: paste ("дергать") (мы вернулись на круги своя)
  • C-y: вставьте еще раз (теперь у нас есть две копии строки)

Они оба выглядят досадно многословно по сравнению с 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")

(Версия elisp @ Nathan, вероятно, предпочтительнее, потому что она не сломается при изменении привязки клавиш.)

Осторожно: некоторые режимы Emacs могут использовать C-c C-d для чего-то другого.

Здравствуй! Имейте в виду, что если у вас есть '(setq kill-all-line t)', вам понадобится только один 'C-k' (решение 2), поскольку он уже уничтожает новую строку вместе с содержимым строки. Я предпочитаю использовать «C-k». Привет, Даниэль

danielpoe 16.02.2009 09:30

Это действительно неловко.

tofutim 22.06.2012 00:09

Что насчет C-S-backspace C-y C-y?

ericzma 07.01.2013 09:16

Было бы неплохо иметь версию, которая делала бы это без изменения списка уничтожений или положения курсора.

Ollie Saunders 12.06.2013 15:06

Вы думаете, что Emacs не может этого сделать? stackoverflow.com/questions/637351/…

Chris Conway 12.06.2013 20:17

Несколько проще выбрать C-S-Backspace, а затем C-yC-y. Это означает убить текущую полную строку, а затем вернуть ее дважды.

katox 16.09.2013 20:43

@tofutim Действительно. В Netbeans я делаю C-S-down.

Peter Wood 14.11.2013 15:37

@PeterWood Серьезно? Вы думаете, что эта операция так важна, чтобы ее должен было сопоставлено с одним нажатием клавиши? Я делаю это в Emacs буквально каждый день, и приведенная выше ключевая последовательность никогда не приходит мне в голову.

Chris Conway 14.11.2013 23:52

что такое M-w? какой ключ использовать для этого?

Bala 17.12.2013 16:15

@Bala "M" - это "Meta" (обычно Esc или Alt, это зависит от раскладки клавиатуры). «M-w» - это «Meta» и «w» одновременно (на моей клавиатуре «Alt-w»).

Chris Conway 17.12.2013 23:33

Это плохой ответ, его нельзя рассматривать как принятый. Использование привязок клавиш приводит к неожиданным последствиям, особенно когда люди повторно связывают клавиши по умолчанию.

Ha-Duong Nguyen 25.08.2016 11:12

Вы должны попробовать режим великого зла

McBear Holden 07.02.2017 11:04

В дополнение к предыдущим ответам вы также можете определить свою собственную функцию для дублирования строки. Например, добавление следующего в ваш файл .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)

Я получаю следующую ошибку: Symbol's function definition is void: move-beginning-of-line

Rohaq 13.03.2012 19:24

Проблема в том, что клавиша «Del» также привязана к дублированию строки ...

David Gomes 16.03.2012 01:50

Итак, есть идеи, как отвязать Del от этой функции?

Alexander Shcheblikin 08.11.2014 17:33

Хорошо, найдено решение для возврата Del к нормальному состоянию при сохранении нового C-d: (global-set-key (kbd "<delete>") 'delete-char) необходимо добавить после определения C-d.

Alexander Shcheblikin 08.11.2014 18:56

Попытка сделать это с пустой строкой приведет к вставке двух строк вместо одной. Не знаю почему. Есть простое решение?

Zelphir Kaltstahl 22.11.2015 19:15

У меня copy-from-above-command привязан к ключу и я использую его. Он поставляется с XEmacs, но я не знаю о GNU Emacs.

`copy-from-above-command' is an interactive compiled Lisp function
-- loaded from "/usr/share/xemacs/21.4.15/lisp/misc.elc" (copy-from-above-command &optional ARG)

Documentation: Copy characters from previous nonblank line, starting just above point. Copy ARG characters, but not past the end of that line. If no argument given, copy the entire rest of the line. The characters copied are inserted in the buffer before point.

Что касается версии 23, она также является частью стандартного дистрибутива GNU Emacs.

viam0Zah 10.08.2010 11:20

Похоже, в моей версии этого нет. Нужно что-то загружать? Моя версия - GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped].

qmega 24.12.2010 05:55

@qmega Вам нужно сделать (требуется 'разное').

Dmitry 21.10.2011 23:07

Добавление Натана к вашему файлу .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)

Это хорошо. Спасибо!

tejasbubane 04.05.2017 17:40

(progn (начало строки) (вставить (строку объекта в точке)))

knobo 27.08.2020 13:25

то, что вы, возможно, захотите иметь в своем .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 ....

Я не совсем помню, как дублирование строк работает где-либо еще, но как бывший пользователь SciTE мне понравилось одно в SciTE-way: он не затрагивает позицию курсора! Так что все вышеперечисленные рецепты мне не подошли, вот моя хиппи-версия:

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

Моя версия функции для дублирования строки, которая хорошо работает с отменой и не влияет на положение курсора. Это был результат обсуждение в gnu.emacs.sources от ноября 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))

Затем вы можете определить CTRL-D для вызова этой функции:

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

Отлично! Функция отмены и положения курсора делает это лучше всего. Спасибо!

ptrn 02.06.2011 19:54

также по ссылке есть код для регионов!

pcarvalho 03.03.2014 01:49

Очень красивое решение. Спасибо

Plankalkül 05.06.2014 15:49

Прекрасно работает. Спасибо за решение.

Stryker 06.08.2017 14:56

@pesche crux-duplicate-current-line-or-region работает лучше для меня, потому что с вашей функцией он отменяет дублирование строк и последнюю операцию.

rofrol 01.08.2018 11:30

«Я написал свою собственную версию 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)

Вместо kill-line (C-k), как в C-aC-kC-kC-yC-y, используйте команду kill-whole-line:

C-S-Backspace
C-y
C-y

Преимущества по сравнению с C-k заключаются в том, что не имеет значения, где находится точка на строке (в отличие от C-k, который требует нахождения в начале строки), а также убивает новую строку (опять же, что-то C-k не делает).

Престижность @RayVega! Я попробовал это решение, и оно работает как чемпион (по крайней мере, в моем GNU Emacs 23.3.1). Это решение не работает для некоторых людей? Это лучший ответ на ваш (собственный) вопрос.

JS. 26.07.2012 21:15

Вы должны принять этот ответ как правильный. Он делает именно то, что вы просили, и с «наименьшим количеством команд».

Davor Cubranic 18.02.2016 21:33

Мне понравилась версия FraGGod, за исключением двух вещей: (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)))))

С аргументами префикса и (надеюсь) интуитивным поведением:

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

Вот еще одна функция для этого. Моя версия не касается кольца уничтожения, и курсор оказывается на новой строке там, где он был в оригинале. Он будет дублировать область, если она активна (режим переходной метки), или по умолчанию дублирует линию в противном случае. Он также сделает несколько копий, если задан префикс 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, за которым следует единственная (немодифицированная) буква, зарезервирована для привязок пользователей.

Я помещаю это в свой файл .emacs, но когда пытаюсь использовать C-c d, я получаю сообщение об ошибке command-execute: Wrong type argument: commandp, duplicate-line-or-region. Есть идеи, что случилось? Я использую Emacs 25.1.1 в Windows

junius 17.03.2017 20:03

Действительно хорошее решение, я ценю функцию региона и функцию комментирования с отрицательным аргументом. Также как и предлагаемая привязка клавиш.

Alex Trueman 11.04.2017 21:51

;; 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, чтобы дублировать строку.

Самый простой способ - это метод Криса Конвея.

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

Это способ по умолчанию, установленный EMACS. На мой взгляд, лучше стандартный. Я всегда осторожно отношусь к настройке собственной привязки клавиш в EMACS. EMACS уже достаточно мощный, я думаю, мы должны постараться адаптироваться к его собственным привязкам клавиш.

Хотя это немного длинновато, но когда вы к этому привыкнете, вы сможете делать это быстро, и это будет весело!

Учитывая все обстоятельства, Emacs требует очень мало - огромная выгода, которую он дает вам, - это легкость настройка it для ваших собственных нужд. Конечно, на практике существует находятся множество стандартных способов делать вещи, которых полезно придерживаться, но если вы используете Emacs по умолчанию и делаете что-то более сложный, чем необходимо, просто потому, что вы думаете, что «лучше использовать стандарт» , вы в значительной степени делаете это неправильно.

phils 12.11.2013 01:34

В последних версиях emacs вы можете использовать M-w в любом месте строки, чтобы скопировать его. Так получается:

M-w C-a RET C-y

Действительно? Какой "недавний" Emacs это был бы? Не в случае с 24.4: вы получите «Отметка не установлена, поэтому нет региона».

Davor Cubranic 18.02.2016 21:30

текущий Emacs - 24,5, а M-w привязан к easy-kill. Проверьте, что вы получите, когда сделаете C-h c M-w

Louis Kottmann 19.02.2016 13:49

Не работал в Emacs 24.5.1. Копируется только от начала строки до точки в начале той же строки после вставки предыдущей пустой строки.

Derek Mahar 30.11.2017 19:05

Я пишу один по своему усмотрению.

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

установить дубликат из мелпы:

M-x package-install RET-дубликат

и добавьте эту привязку к файл инициализации:

(global-set-key (kbd "M-c") 'дубликат)

Похоже, к этим датам их нет.

MarkSkayff 26.05.2020 01:11

При интерактивном вызове без активной области, вместо этого КОПИРУЙТЕ (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)))))

При интерактивном вызове без активной области, вместо этого нажмите 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)

Во всяком случае, я видел очень сложные решения ...

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

Обратите внимание, что это будет бесполезно с кольцом уничтожения.

Dodgie 18.01.2018 23:53

Это добавляет строку к себе, когда это последняя строка, и файл не заканчивается новой строкой

Mark 11.08.2018 20:21

Эта функциональность должна совпадать с реализацией 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))

И тогда у меня это связано с мета + shift + d

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

Есть пакет под названием Avy. В нем есть команда avy-copy-line. Когда вы используете эту команду, каждая строка в вашем окне получает буквенную комбинацию. Затем вам просто нужно набрать комбинацию, и вы получите эту строку. Это также работает для региона. Тогда вам просто нужно набрать две комбинации.

Здесь вы можете увидеть интерфейс:

Вот функция для дублирования текущей строки. С аргументами префикса строка будет дублироваться несколько раз. Например, C-3 C-S-o дублирует текущую строку три раза. Не меняет кольцо убийства.

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

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

Я не могу поверить во все эти сложные решения. Это два нажатия клавиш:

<C-S-backspace> запускает команду kill-all-line

C-/ запускает команду отмены

Итак, <C-S-backspace> C-/ «копирует» всю строку (уничтожает и отменяет).

Конечно, вы можете комбинировать это с числовыми и отрицательными аргументами, чтобы уничтожить несколько строк вперед или назад.

Это кажется более естественным по сравнению с выбранным ответом Криса Конвея.

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

Это позволяет дублировать строку несколько раз, просто повторяя нажатия клавиш \ C-c \ C-d.

Как упоминалось в других ответах, привязка нажатий клавиш к шепелявому коду - лучшая идея, чем привязка их к другим клавишам. В ответе @mw код дублирует строку и перемещает метку в конец новой строки. Эта модификация сохраняет позицию метки в том же столбце в новой строке:

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

M-c, Shift+Insertx2 (или любой другой ярлык для вставки) сделает это.

Если вы используете Spacemacs, вы можете просто использовать duplicate-line-or-region, привязанный к:

SPC x l d 

На Melpa есть пакет под названием «move-dup», который может вам в этом помочь.

Отказ от ответственности: я являюсь автором этого пакета.

Другие вопросы по теме