development

emacs에서 줄 / 영역을 위아래로 이동

big-blog 2020. 10. 12. 07:50
반응형

emacs에서 줄 / 영역을 위아래로 이동


emacs에서 선택한 영역이나 선 (선택 사항이없는 경우)을 위아래로 이동하는 가장 쉬운 방법은 무엇입니까? 이클립스와 동일한 기능을 찾고 있습니다 (M-up, M-down으로 제한됨).


바인딩 된 조옮김 선을 사용하여 선을 이동할 수 있습니다 C-x C-t. 그러나 지역에 대해서는 Dunno.

바인딩을 변경해야하는 경우를 제외하고 원하는 작업을 수행하는 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!

이클립스 Alt+ Up/ Down단일 라인과 선택된 영역 라인에 대해 정확히 작동합니다 !

그 외에도 Alt+ Left/ 로 단어를 이동할 수 있습니다. Right
이것은 정확히 당신이 찾고있는 것입니다! ELPA repos 에서도 사용할 수 있습니다 !

다른 솔루션은 저에게 효과가 없었습니다. 그들 중 일부는 버그가 있었으며 (순서를 바꾸는 동안 줄 바꿈, wtf?) 일부는 정확히 선택된 영역을 이동하여 선의 선택되지 않은 부분을 위치에 남겨 둡니다. 그러나 drag-stuff일식에서와 똑같이 작동합니다!

그리고 더! 지역을 선택하고 Alt+ Left/ Right! 선택한 영역을 왼쪽 또는 오른쪽으로 한 문자 씩 조옮김합니다. 놀랄 만한!

전역 적으로 활성화하려면 다음을 실행하십시오.

(drag-stuff-global-mode)

줄을 위 / 아래로 이동하기위한 몇 가지 대화 형 함수를 작성했습니다.

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

The keybindings are IntelliJ IDEA style, but you can use anything you want. I should probably implement some functions that operate on regions as well.


There is an entry in the emacs wiki just for this:

http://www.emacswiki.org/emacs/MoveLine

For moving regions:

http://www.emacswiki.org/emacs/MoveRegion


Here is my snippet to move the current line or the lines spanned by the active region. It respects cursor position and highlighted region. And it won't break lines when the region doesn't begin/end at line border(s). (It is inspired by eclipse; I found the eclipse way more convenient than 'transpose-lines'.)

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

There's no built-in. You can use transpose-lines (C-x C-t) but you cannot use it repeatedly. Look at the functions on http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/.

It should be easy to adapt that to regions, too.


The transpose-paragraph function could help you.

You might also want to have a look to the transpose section in the Emacs manual. Essentially:

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

I use the smart-shift package (in Melpa) for this. By default it rebinds C-C <arrow> to move a line or region. It moves horizontally by a major-mode-specific amount (e.g. c-basic-offset or python-indent-offset). Works on regions also.

;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
  (global-smart-shift-mode 1))

참고URL : https://stackoverflow.com/questions/2423834/move-line-region-up-and-down-in-emacs

반응형