2010-03-11 42 views
74

在emacs中向上或向下移動所選區域或行(如果沒有選擇),最簡單的方法是什麼?我正在尋找與eclipse中相同的功能(以M-up,M-down爲界)。在emacs中向上和向下移動行/區域

+1

我敢肯定,這個習慣用法是殺死你想要移動的東西,使用通常的導航功能(包括isearch等)來移動你想要的代碼點,然後將yank 。記住,有一堆殺死的東西,所以你甚至不必立即找到位置;你可以收集其他比特以便稍後抽出。就個人而言,作爲一個沉重的Emacs用戶,我無法想象任何情況下,我寧願手動移動一行或一行。它不會有用。 – jrockway 2010-03-12 02:27:36

+5

@jrockway:感謝您的評論。我認爲每個人都有自己的做事方式。我在eclipse上工作很多,我非常習慣於移動線條/區域。 emacs非常具有可擴展性的好處之一是可以輕鬆添加此功能。 – fikovnik 2010-03-14 15:18:08

+2

同意。我經常想按照你所描述的來上下移動線條,不管我是否在支持它的編輯器中。或者,就此而言,我是否正在處理代碼。 Word支持(按段落)Alt + Shift +向上和向下,並且我可以在我的編輯器中將其映射。 – harpo 2010-09-28 00:47:21

回答

35

一條線可以使用transpose-lines綁定到C-x C-t。不過不知道地區。

我找到了this 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) 
+0

感謝您的摘錄。這正是我所期待的! – fikovnik 2010-03-14 15:25:22

+0

非常好! – 2013-07-04 12:23:13

+0

這個解決方案和@sanityinc發佈的幾乎完全相同:如果我使用定義的快捷方式向上和/或向下移動區域,則立即使用快捷方式進行撤消(默認爲C-_) ,該地區就消失了,消息「撤消在地區!」顯示在回聲區域中。另一個撤銷命令產生消息「沒有進一步的區域撤消信息」。但是,如果我移動光標,然後命令撤消,撤消重新開始工作。一個相對較小的刺激,但所有其他的Emacs命令可以立即撤消,而不訴諸於詭計。 – 2013-07-15 13:06:31

1

沒有內置的。您可以使用轉置線(C-x C-t),但不能反覆使用。看看http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/上的功能。

它也應該很容易適應地區。

+0

+1,我在我的.emacs中有這樣的東西,非常方便 – 2010-03-11 13:06:09

+1

順便說一句,如果你決定使用鏈接的片段,你可能希望將let語句改爲(let((col(current-column))(line-move-visual nil)),否則你會用包裝線獲得有趣的行爲。 – 2010-03-11 14:47:48

1

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). 
8

我已經寫了幾個互動功能動線向上/向下:

;; 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的風格,但你可以使用任何你想要的。我也許應該實現一些在各個地區運作的功能。

43

更新:安裝Marmalade的move-text包或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) 
+0

我已經將它添加到EmacsWiki中,它在這裏:http://www.emacswiki.org/emacs/MoveText – ocodo 2010-10-04 22:48:25

+0

謝謝!我認爲代碼已經在那裏(http://www.emacswiki.org/emacs/basic-edit-toolkit.el),但這個新的頁面將會更容易讓人找到。 – sanityinc 2010-10-05 08:59:57

+0

啊,很酷我以前沒見過,看起來像basic-edit-toolkit可以使用清理。 – ocodo 2010-10-05 21:42:43

4

這裏是我的代碼片段來移動當前行或活動區域跨越的行。它尊重光標位置和突出顯示的區域。當該區域不以線邊界開始/結束時,它不會斷線。 (它是由偏食的啓發,我找到了日食的方式比「轉線」更方便。)

;; 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))) 
+1

對我來說,移動文本包被打破了。您的解決方案在我的系統上完美運行感謝那! – 2016-01-31 17:07:42

21

你應該嘗試drag-stuff

它的工作原理完全一樣日食Alt鍵 + 向上/單線條,以及符合所選區域的線!

此外,它可以讓你與Alt鍵 + /
這正是你要尋找移動的話!它甚至可以從ELPA repos

其他解決方案從來沒有爲我工作。其中一些是越野車(在改變順序的同時換位線,wtf?),其中一些正在移動恰好選定的區域,而未選定部分的線位於其位置上。但是drag-stuff和eclipse完全一樣!

甚至更​​多!您可以嘗試選擇一個區域並使用Alt + Left/Right!這會將所選區域左移或右移一個字符。驚人!

要啓用全局簡單地運行這樣的:

(drag-stuff-global-mode) 
+0

它確實需要左右移動可選,因爲它覆蓋了默認的emacs鍵盤映射。 – ocodo 2014-10-23 13:21:28

+0

@Slomojo也許!你爲什麼不建議在emacswiki上? :) – 2014-10-23 19:37:32

+0

乾脆就像一個魅力工作 – blackwind 2015-03-08 03:19:18

0

我用的是智能換檔組件(在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))