Я бачив це саме запитання до 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 ("yank")Вищезгадане
C-a C-k C-k C-y C-y
становить одне і те ж (TMTOWTDI)
C-a
: переміщення курсору до початку рядкаC-k
: перерізати ("вбити") рядок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")
(@ Натанова еліпсова версія, мабуть, краща, тому що вона не порушиться, якщо будь-яке з ключових прив’язок буде змінено.)
Будьте обережні: деякі режими 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
не робиться).
Ось ще одна функція для цього. Моя версія не торкається кільця вбивства, і курсор опиняється на новому рядку, де він був у оригіналі. Він буде дублювати область, якщо вона активна (режим перехідних позначок) або за замовчуванням дублює рядок інакше. Він також зробить кілька копій, якщо їм буде наданий префікс 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
яким іншим способом, оскільки супроводжується одним (немодифікованим) листом, зарезервованим для прив'язки користувачів.
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 пакет-встановити RET дублікат
і додайте це прив'язку клавіш до файлу init :
(global-set-key (kbd "Mc") "дублікат-річ"
Я не дуже пам'ятаю, як працює дублювання ліній деінде, але мені як колишньому користувачеві SciTE сподобалось одне про SciTE-шлях: воно не торкається положення курсору! Отже, всі відповіді вище для мене були недостатньо хорошими, ось моя хіпі-версія:
(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))))
Зауважте, що нічого не вбивається в процесі, залишаючи сліди та поточний відбір недоторканими.
До речі, чому ви так любите хитатися курсором навколо, коли є ця приємна 'n'clean вбивство-ціла лінія' (CS-backspace)?
тому що я не знаю, я розпочну цей раунд з гольфу з slowball:
ctrl-k, y, y
щось, що ви хочете мати у своїх .emacs, це
(setq kill-whole-line t)
Що в основному вбиває весь рядок плюс новий рядок, коли ви викликаєте лінію вбивства (тобто через 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-above-command '- це інтерактивна компільована функція Lisp,
завантажена з" /usr/share/xemacs/21.4.15/lisp/misc.elc "(копіювати з-над-команди та необов'язково 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це захопити персонаж нового рядка. Його можна видалити, якщо ви просто хочете текст.
Коли викликуєте інтерактивно, не маючи активного регіону, натомість скопіюйте один рядок:
(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)