Який найпростіший спосіб перемістити вибраний регіон або лінію (якщо немає виділення) вгору або вниз в emacs? Я шукаю ту ж функціональність, що і в eclipse (обмежена M-up, M-down).
Який найпростіший спосіб перемістити вибраний регіон або лінію (якщо немає виділення) вгору або вниз в emacs? Я шукаю ту ж функціональність, що і в eclipse (обмежена M-up, M-down).
Відповіді:
Рядок можна переміщати за допомогою ліній транспонування, прив'язаних до C-x C-t
. Не знаю про регіони.
Я знайшов цей фрагмент elisp, який робить те, що ви хочете, за винятком того, що вам потрібно змінити прив'язки.
(defun move-text-internal (arg)
(cond
((and mark-active transient-mark-mode)
(if (> (point) (mark))
(exchange-point-and-mark))
(let ((column (current-column))
(text (delete-and-extract-region (point) (mark))))
(forward-line arg)
(move-to-column column t)
(set-mark (point))
(insert text)
(exchange-point-and-mark)
(setq deactivate-mark nil)))
(t
(beginning-of-line)
(when (or (> arg 0) (not (bobp)))
(forward-line)
(when (or (< arg 0) (not (eobp)))
(transpose-lines arg))
(forward-line -1)))))
(defun move-text-down (arg)
"Move region (transient-mark-mode active) or current line
arg lines down."
(interactive "*p")
(move-text-internal arg))
(defun move-text-up (arg)
"Move region (transient-mark-mode active) or current line
arg lines up."
(interactive "*p")
(move-text-internal (- arg)))
(global-set-key [\M-\S-up] 'move-text-up)
(global-set-key [\M-\S-down] 'move-text-down)
Оновлення: Встановіть move-text
пакет від Marmalade або MELPA, щоб отримати такий код.
Ось те, що я використовую, що працює як в регіонах, так і в окремих рядках:
(defun move-text-internal (arg)
(cond
((and mark-active transient-mark-mode)
(if (> (point) (mark))
(exchange-point-and-mark))
(let ((column (current-column))
(text (delete-and-extract-region (point) (mark))))
(forward-line arg)
(move-to-column column t)
(set-mark (point))
(insert text)
(exchange-point-and-mark)
(setq deactivate-mark nil)))
(t
(let ((column (current-column)))
(beginning-of-line)
(when (or (> arg 0) (not (bobp)))
(forward-line)
(when (or (< arg 0) (not (eobp)))
(transpose-lines arg)
(when (and (eval-when-compile
'(and (>= emacs-major-version 24)
(>= emacs-minor-version 3)))
(< arg 0))
(forward-line -1)))
(forward-line -1))
(move-to-column column t)))))
(defun move-text-down (arg)
"Move region (transient-mark-mode active) or current line
arg lines down."
(interactive "*p")
(move-text-internal arg))
(defun move-text-up (arg)
"Move region (transient-mark-mode active) or current line
arg lines up."
(interactive "*p")
(move-text-internal (- arg)))
(global-set-key [M-S-up] 'move-text-up)
(global-set-key [M-S-down] 'move-text-down)
Вам слід спробувати drag-stuff
!
Він працює точно так само, як eclipse Alt+ Up/ Downдля окремих рядків, а також для вибраних ліній регіону!
На додаток до цього він дозволяє переміщати слова за допомогою Alt+ Left/ Right
Це саме те, що ви шукаєте! І він навіть доступний у репозиторіях ELPA !
Інші рішення ніколи не працювали для мене. Деякі з них глючили (транспонували лінії, змінюючи порядок, wtf?), А деякі рухалися в точно обраній області, залишаючи невиділені частини ліній на своїх позиціях. Але drag-stuff
працює точно так само, як у затемненні!
І навіть більше! Ви можете спробувати вибрати регіон і скористатися Alt+ Left/ Right! Це перемістить вибрану область на один символ ліворуч або праворуч. Дивовижний!
Щоб увімкнути його глобально, просто запустіть це:
(drag-stuff-global-mode)
(drag-stuff-define-keys)
файлу init до того, як клавіатури почнуть працювати. Це пояснюється у цьому github: github.com/rejeep/drag-stuff.el
Я написав пару інтерактивних функцій для переміщення рядків вгору / вниз:
;; move line up
(defun move-line-up ()
(interactive)
(transpose-lines 1)
(previous-line 2))
(global-set-key [(control shift up)] 'move-line-up)
;; move line down
(defun move-line-down ()
(interactive)
(next-line 1)
(transpose-lines 1)
(previous-line 1))
(global-set-key [(control shift down)] 'move-line-down)
Клавіатури пов’язані зі стилем IntelliJ IDEA, але ви можете використовувати все, що завгодно. Ймовірно, мені слід реалізувати деякі функції, що діють і на регіони.
Ось мій фрагмент для переміщення поточного рядка або рядків, що охоплюються активною областю. Він поважає положення курсору та виділену область. І це не буде розривати лінії, коли регіон не починається / не закінчується на кордоні лінії. (Він натхненний затемненням; я знайшов спосіб затемнення більш зручним, ніж `` транспонування ліній ''.)
;; move the line(s) spanned by the active region up/down (line transposing)
;; {{{
(defun move-lines (n)
(let ((beg) (end) (keep))
(if mark-active
(save-excursion
(setq keep t)
(setq beg (region-beginning)
end (region-end))
(goto-char beg)
(setq beg (line-beginning-position))
(goto-char end)
(setq end (line-beginning-position 2)))
(setq beg (line-beginning-position)
end (line-beginning-position 2)))
(let ((offset (if (and (mark t)
(and (>= (mark t) beg)
(< (mark t) end)))
(- (point) (mark t))))
(rewind (- end (point))))
(goto-char (if (< n 0) beg end))
(forward-line n)
(insert (delete-and-extract-region beg end))
(backward-char rewind)
(if offset (set-mark (- (point) offset))))
(if keep
(setq mark-active t
deactivate-mark nil))))
(defun move-lines-up (n)
"move the line(s) spanned by the active region up by N lines."
(interactive "*p")
(move-lines (- (or n 1))))
(defun move-lines-down (n)
"move the line(s) spanned by the active region down by N lines."
(interactive "*p")
(move-lines (or n 1)))
Вбудованого не існує. Ви можете використовувати лінії транспонування (Cx Ct), але ви не можете використовувати їх повторно. Подивіться на функції на http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/ .
Це повинно бути легко адаптувати до регіонів.
transpose-paragraph
Функція може допомогти вам.
Можливо, ви також захочете поглянути на розділ транспонування в посібнику Emacs. По суті:
C-t
Transpose two characters (transpose-chars).
M-t
Transpose two words (transpose-words).
C-M-t
Transpose two balanced expressions (transpose-sexps).
C-x C-t
Transpose two lines (transpose-lines).
Для цього я використовую пакет smart-shift (у Мельпі). За замовчуванням він перев'язується C-C <arrow>
для переміщення лінії або регіону. Він рухається горизонтально на величину, залежну від основного режиму (наприклад, c-basic-offset або python-indent-offset). Працює і з регіонами.
;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
(global-smart-shift-mode 1))