Я видел этот же вопрос для VIM, и я сам хотел узнать, как это сделать для Emacs. В ReSharper я использую CTRL-D для этого действия. Какое наименьшее количество команд для выполнения этого в Emacs?
Я видел этот же вопрос для VIM, и я сам хотел узнать, как это сделать для Emacs. В ReSharper я использую CTRL-D для этого действия. Какое наименьшее количество команд для выполнения этого в Emacs?
Ответы:
я использую
C-a C-SPACE C-n M-w C-y
который разбивается на
C-a
: переместить курсор в начало строкиC-SPACE
: начать выбор («установить отметку»)C-n
: переместить курсор на следующую строкуM-w
: копия регионаC-y
: paste ("янки")Вышеупомянутое
C-a C-k C-k C-y C-y
составляет одно и то же (TMTOWTDI)
C-a
: переместить курсор в начало строкиC-k
: cut ("kill") строкаC-k
: вырезать новую строкуC-y
: paste ("yank") (мы вернулись на круги своя)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
чтобы делать что-то еще.
C-S-backspace C-y C-y
?
В дополнение к предыдущим ответам вы также можете определить свою собственную функцию для дублирования строки. Например, добавив следующее в ваш файл .emacs, вы заставите Cd дублировать текущую строку.
(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
Del
от этой функции?
Del
к нормальному состоянию с сохранением нового C-d
: (global-set-key (kbd "<delete>") 'delete-char)
необходимо добавить после C-d
определения.
Поместите курсор на строку, если не в начале, сделайте CTRL- A, тогда:
CTRL-K
CTRL-K
CTRL-Y
CTRL-Y
Моя версия функции для дублирования строки, которая хорошо работает с отменой и не портит позицию курсора. Это было результатом обсуждения в 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)
crux-duplicate-current-line-or-region
работает лучше для меня, потому что с вашей функцией он отменяет дублирование строк и последнюю операцию.
Вместо kill-line
( C-k
) C-a
C-k
C-k
C-y
C-y
используется kill-whole-line
команда:
C-S-Backspace
C-y
C-y
Преимущества перед этим C-k
включают в себя то, что не имеет значения, где находится точка на линии (в отличие от C-k
которой требуется находиться в начале линии), а также убивает символ новой строки (опять же, что-то C-k
не так).
Вот еще одна функция для этого. Моя версия не касается кольца уничтожения, и курсор оказывается на новой строке, где он был на оригинале. Он будет дублировать регион, если он активен (режим переходной метки), или по умолчанию дублирует строку в противном случае. Он также сделает несколько копий, если ему присваивается префиксный аргумент, и закомментирует исходную строку, если ему присваивается отрицательный префиксный аргумент (это полезно для тестирования другой версии команды / оператора при сохранении старой).
(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
после одной (неизмененной) буквы зарезервировано для привязок пользователя.
C-c d
я получаю ошибку command-execute: Wrong type argument: commandp, duplicate-line-or-region
. Есть идеи, что случилось? Я использую Emacs 25.1.1 на Windows
Добавление Натана в ваш файл .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)
установить двойную вещь из melpa:
Mx package-install RET duplicate-вещь
и добавьте эту привязку клавиш в файл инициализации :
(global-set-key (kbd "Mc") 'duplicate-thing)
Я не совсем помню, как дублирование строк работает где-то еще, но как бывший пользователь 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))))
Обратите внимание, что на самом деле ничто не убивается в процессе, оставляя метки и текущий выбор без изменений.
Кстати, почему вы, ребята, так любите дергать курсором, когда есть эта приятная и чистая вещь, убивающая всю линию (CS-backspace)?
потому что я не знаю, я начну этот раунд игры в гольф с медленным мячом:
ctrl-k, y, y
то, что вы можете захотеть иметь в вашем .emacs
(setq kill-whole-line t)
Который в основном убивает всю строку плюс новую строку всякий раз, когда вы вызываете kill-line (т.е. через Ck). Тогда без лишнего кода, вы можете просто сделать Ca Ck Cy Cy, чтобы продублировать строку. Это ломается к
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.
Но если вы используете это часто, то, возможно, лучше было бы использовать выделенную привязку ключа, но преимущество простого использования Ca Ck Cy Cy заключается в том, что вы можете дублировать строку в другом месте, а не чуть ниже текущей строки.
Я copy-from-above-command
связался с ключом и использую это. Он поставляется с XEmacs, но я не знаю о GNU Emacs.
`copy-from-over-command '- это интерактивная скомпилированная функция Lisp,
загружаемая из" /usr/share/xemacs/21.4.15/lisp/misc.elc "(команда copy-from-вышеуказанная-команда & необязательный ARG)Документация: Скопируйте символы из предыдущей непустой строки , начиная чуть выше точки. Скопируйте символы ARG, но не после конца этой строки. Если аргумент не указан, скопируйте всю оставшуюся часть строки. Скопированные символы вставляются в буфер перед точкой.
GNU Emacs 23.2.1 (amd64-portbld-freebsd8.1) of 2010-11-14 on [host clipped]
.
Существует пакет под названием Avy. Он имеет команду avy-copy-line. Когда вы используете эту команду, каждая строка в вашем окне получает комбинацию букв. Тогда вам просто нужно набрать комбинацию, и вы получите эту строку. Это также работает для региона. Тогда вам просто нужно набрать две комбинации.
Здесь вы можете увидеть интерфейс:
Значения по умолчанию ужасны для этого. Однако вы можете расширить 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 ...
.
«Я написал свою собственную версию 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)
Мне понравилась версия 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)))))
В последних версиях Emacs вы можете использовать Mw в любом месте строки, чтобы скопировать его. Так и становится:
M-w C-a RET C-y
M-w
связан с easy-kill
. Проверьте, что вы получаете, когда делаетеC-h c M-w
Во всяком случае, я видел очень сложные решения ...
(defun duplicate-line ()
"Duplicate current line"
(interactive)
(kill-whole-line)
(yank)
(yank))
(global-set-key (kbd "C-x M-d") 'duplicate-line)
ctrl- k, ctrl- k, (позиция в новом месте)ctrl -y
Добавьте ctrl- aесли вы не начинаете с начала строки. А 2-й ctrl- kэто захватить символ новой строки. Его можно удалить, если вы просто хотите текст.
При интерактивном вызове без активной области, COPY (Mw) вместо одной строки:
(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 (Cw) вместо одной строки.
(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)
(let ((text (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
(cur-col (current-column)))
(end-of-line) (insert "\n" text)
(beginning-of-line) (right-char cur-col)))
(global-set-key (kbd "C-c d l") 'duplicate-line)
Но я обнаружил, что это будет иметь некоторые проблемы, когда текущая строка содержит многобайтовые символы (например, символы CJK). Если вы столкнулись с этой проблемой, попробуйте это:
(defun duplicate-line ()
"Duplicate current line."
(interactive)
(let* ((text (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
(cur-col (length (buffer-substring-no-properties (point-at-bol) (point)))))
(end-of-line) (insert "\n" text)
(beginning-of-line) (right-char cur-col)))
(global-set-key (kbd "C-c d l") 'duplicate-line)
Эта функциональность должна соответствовать реализации JetBrains с точки зрения дублирования как по линии, так и по региону, а затем покидания точки и / или активной области, как ожидается:
Просто обертка вокруг интерактивной формы:
(defun wrx/duplicate-line-or-region (beg end)
"Implements functionality of JetBrains' `Command-d' shortcut for `duplicate-line'.
BEG & END correspond point & mark, smaller first
`use-region-p' explained:
http://emacs.stackexchange.com/questions/12334/elisp-for-applying-command-to-only-the-selected-region#answer-12335"
(interactive "r")
(if (use-region-p)
(wrx/duplicate-region-in-buffer beg end)
(wrx/duplicate-line-in-buffer)))
Который называет это,
(defun wrx/duplicate-region-in-buffer (beg end)
"copy and duplicate context of current active region
|------------------------+----------------------------|
| before | after |
|------------------------+----------------------------|
| first <MARK>line here | first line here |
| second item<POINT> now | second item<MARK>line here |
| | second item<POINT> now |
|------------------------+----------------------------|
TODO: Acts funky when point < mark"
(set-mark-command nil)
(insert (buffer-substring beg end))
(setq deactivate-mark nil))
Или это
(defun wrx/duplicate-line-in-buffer ()
"Duplicate current line, maintaining column position.
|--------------------------+--------------------------|
| before | after |
|--------------------------+--------------------------|
| lorem ipsum<POINT> dolor | lorem ipsum dolor |
| | lorem ipsum<POINT> dolor |
|--------------------------+--------------------------|
TODO: Save history for `Cmd-Z'
Context:
http://stackoverflow.com/questions/88399/how-do-i-duplicate-a-whole-line-in-emacs#answer-551053"
(setq columns-over (current-column))
(save-excursion
(kill-whole-line)
(yank)
(yank))
(let (v)
(dotimes (n columns-over v)
(right-char)
(setq v (cons n v))))
(next-line))
И тогда у меня есть это связано с мета + Shift + D
(global-set-key (kbd "M-D") 'wrx/duplicate-line-or-region)
Как упоминалось в других ответах, связывание нажатий клавиш с кодом lisp - это лучшая идея, чем связывание их с другими нажатиями клавиш. С ответом @ mw код дублирует строку и перемещает метку в конец новой строки. Эта модификация сохраняет положение метки в том же столбце на новой строке:
fun duplicate-line ()
(interactive)
(let ((col (current-column)))
(move-beginning-of-line 1)
(kill-line)
(yank)
(newline)
(yank)
(move-to-column col)))
Если вы используете Spacemacs, вы можете просто использовать duplicate-line-or-region
, привязанный к:
SPC x l d
С префиксными аргументами и интуитивным поведением (я надеюсь):
(defun duplicate-line (&optional arg)
"Duplicate it. With prefix ARG, duplicate ARG times."
(interactive "p")
(next-line
(save-excursion
(let ((beg (line-beginning-position))
(end (line-end-position)))
(copy-region-as-kill beg end)
(dotimes (num arg arg)
(end-of-line) (newline)
(yank))))))
Курсор останется на последней строке. Кроме того, вы можете указать префикс для дублирования следующих нескольких строк:
(defun duplicate-line (&optional arg)
"Duplicate it. With prefix ARG, duplicate ARG times."
(interactive "p")
(save-excursion
(let ((beg (line-beginning-position))
(end
(progn (forward-line (1- arg)) (line-end-position))))
(copy-region-as-kill beg end)
(end-of-line) (newline)
(yank)))
(next-line arg))
Я часто использую оба, используя функцию-обертку, чтобы переключать поведение аргумента префикса.
И связывание клавиш:
(global-set-key (kbd "C-S-d") 'duplicate-line)
;; http://www.emacswiki.org/emacs/WholeLineOrRegion#toc2
;; cut, copy, yank
(defadvice kill-ring-save (around slick-copy activate)
"When called interactively with no active region, copy a single line instead."
(if (or (use-region-p) (not (called-interactively-p)))
ad-do-it
(kill-new (buffer-substring (line-beginning-position)
(line-beginning-position 2))
nil '(yank-line))
(message "Copied line")))
(defadvice kill-region (around slick-copy activate)
"When called interactively with no active region, kill a single line instead."
(if (or (use-region-p) (not (called-interactively-p)))
ad-do-it
(kill-new (filter-buffer-substring (line-beginning-position)
(line-beginning-position 2) t)
nil '(yank-line))))
(defun yank-line (string)
"Insert STRING above the current line."
(beginning-of-line)
(unless (= (elt string (1- (length string))) ?\n)
(save-excursion (insert "\n")))
(insert string))
(global-set-key (kbd "<f2>") 'kill-region) ; cut.
(global-set-key (kbd "<f3>") 'kill-ring-save) ; copy.
(global-set-key (kbd "<f4>") 'yank) ; paste.
добавьте вышеупомянутый elisp к вам init.el, и вы получите функцию вырезания / копирования всей строки, затем вы можете F3 F4 дублировать строку.
Самый простой способ - это метод Криса Конвея.
C-a C-SPACE C-n M-w C-y
Это способ по умолчанию, предписанный EMACS. На мой взгляд, лучше использовать стандарт. Я всегда осторожен в настройке собственной привязки ключей в EMACS. EMACS уже достаточно мощный, я думаю, что мы должны стараться изо всех сил адаптироваться к его собственным привязкам клавиш.
Хотя это немного длинно, но когда вы к этому привыкли, вы можете делать быстро и найдете, что это весело!
Вот функция для дублирования текущей строки. С префиксными аргументами, он будет дублировать строку несколько раз. Например, 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-string line))
)))
(global-set-key (kbd "C-S-o") 'duplicate-lines)