Каков самый простой способ перемещения выбранной области или строки (если нет выбора) вверх или вниз в emacs? Я ищу ту же функциональность, что и в eclipse (ограничена M-up, M-down).
Перемещение линии/области вверх и вниз в emacs
Ответ 1
Линию можно перемещать с помощью транспонированных линий, привязанных к C-x C-t
. Тем не менее, о регионах.
Я нашел этот elisp snippet, который делает то, что вы хотите, за исключением того, что вам нужно изменить привязки.
(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)
Ответ 2
Обновление: Установите пакет 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)
Ответ 3
Вам следует попробовать drag-stuff
!
Он работает точно так же, как eclipse Alt + Up/Down для отдельных строк, а также для выбранных линий региона!
В дополнение к этому он позволяет перемещать слова с помощью Alt + Left/Right
Это именно то, что вы ищете! И он даже доступен из репозиториев ELPA!
Другие решения никогда не работали для меня. Некоторые из них были ошибочными (транспонирование линий при изменении их порядка, wtf?), И некоторые из них перемещали точно выбранную область, оставляя невыбранные части линий на своих позициях. Но drag-stuff
работает точно так же, как в eclipse!
И даже больше! Вы можете попробовать выбрать регион и использовать Alt + Left/Right! Это транспонирует выбранную область на один символ влево или вправо. Потрясающе!
Чтобы включить глобально просто запустить это:
(drag-stuff-global-mode)
Ответ 4
Я написал пару интерактивных функций для перемещения строк вверх/вниз:
;; 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, но вы можете использовать все, что хотите. Я должен, вероятно, реализовать некоторые функции, которые работают и с регионами.
Ответ 5
Вот мой фрагмент, чтобы переместить текущую строку или строки, натянутые активной областью. Он учитывает положение курсора и выделенную область. И он не будет ломать линии, когда регион не начнет/не заканчивается на границе границы. (Он вдохновлен eclipse, я нашел способ затмения более удобным, чем "транспонированные линии".)
;; 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)))
Ответ 6
В emacs wiki есть запись только для этого:
http://www.emacswiki.org/emacs/MoveLine
Для движущихся областей:
Ответ 7
Там нет встроенного. Вы можете использовать транспозиционные линии (C-x C-t), но вы не можете использовать их повторно. Посмотрите на функции http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/.
Также легко адаптировать это к областям.
Ответ 8
Функция 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).
Ответ 9
Для этого я использую пакет smart-shift (в Melpa). По умолчанию он перегружает C-C <arrow>
для перемещения строки или области. Он перемещается горизонтально в зависимости от основного режима (например, c-basic-offset или python-indent-offset). Работает также и с регионами.
;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
(global-smart-shift-mode 1))