選択した領域または行(選択がない場合)を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
、Eclipseとまったく同じように機能します!
そしてさらに!地域を選択してAlt+ Left/ Right!を使用してみてください。これにより、選択した領域が1文字ずつ左または右に置き換えられます。すごい!
グローバルに有効にするには、次のコマンドを実行するだけです。
(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)
キーバインディングはIntelliJIDEAスタイルですが、好きなものを使用できます。おそらく、リージョンでも動作するいくつかの関数を実装する必要があります。
これは、現在の行またはアクティブな領域がまたがる行を移動するためのスニペットです。カーソル位置と強調表示された領域を尊重します。また、領域が線の境界で開始/終了しない場合でも、線が途切れることはありません。(日食に触発されています。「転置線」よりも日食の方が便利だと思いました。)
;; 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/の関数を見てください。
それを地域に適応させるのも簡単なはずです。