Qual è il modo più semplice per spostare la regione o la linea selezionata (se non c'è selezione) su o giù in emacs? Sto cercando la stessa funzionalità di eclipse (limitata a M-up, M-down).
Qual è il modo più semplice per spostare la regione o la linea selezionata (se non c'è selezione) su o giù in emacs? Sto cercando la stessa funzionalità di eclipse (limitata a M-up, M-down).
Risposte:
Una linea può essere spostata usando le linee di trasposizione legate a C-x C-t. Non so delle regioni però.
Ho trovato questo frammento di elisp che fa quello che vuoi, tranne per il fatto che devi cambiare le associazioni.
(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)
Aggiornamento: installa il move-textpacchetto da Marmalade o MELPA per ottenere il seguente codice.
Ecco cosa uso, che funziona su entrambe le regioni e singole linee:
(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)
Dovresti provare drag-stuff!
Funziona esattamente come eclipse Alt+ Up/ Downper linee singole, così come per linee regionali selezionate!
Inoltre ti permette di spostare le parole con Alt+ Left/ Right
Questo è esattamente quello che stai cercando! Ed è anche disponibile presso i repository ELPA !
Altre soluzioni non hanno mai funzionato per me. Alcuni di loro erano difettosi (trasponevano le linee mentre cambiavano il loro ordine, wtf?) E alcuni di loro stavano spostando esattamente la regione selezionata, lasciando parti non selezionate delle linee nelle loro posizioni. Ma drag-stufffunziona esattamente come in Eclipse!
E anche di più! Puoi provare a selezionare una regione e utilizzare Alt+ Left/ Right! Questo trasporrà la regione selezionata di un carattere a sinistra oa destra. Sorprendente!
Per abilitarlo a livello globale, esegui semplicemente questo:
(drag-stuff-global-mode)
(drag-stuff-define-keys)nel file init prima che le associazioni di tasti inizino a funzionare. Questo è spiegato in questo github: github.com/rejeep/drag-stuff.el
Ho scritto un paio di funzioni interattive per spostare le righe su / giù:
;; 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)
Le combinazioni di tasti sono in stile IntelliJ IDEA, ma puoi usare tutto ciò che desideri. Probabilmente dovrei implementare alcune funzioni che operano anche sulle regioni.
Ecco il mio frammento per spostare la linea corrente o le linee attraversate dalla regione attiva. Rispetta la posizione del cursore e la regione evidenziata. E non interromperà le linee quando la regione non inizia / finisce al bordo della linea. (È ispirato da eclipse; ho trovato il modo eclipse più conveniente di "trasponi-linee".)
;; 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)))
C'è una voce nel wiki di emacs solo per questo:
http://www.emacswiki.org/emacs/MoveLine
Per spostare le regioni:
Non c'è built-in. Puoi usare le linee di trasposizione (Cx Ct) ma non puoi usarlo ripetutamente. Guarda le funzioni su http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/ .
Dovrebbe essere facile adattarlo anche alle regioni.
La transpose-paragraphfunzione potrebbe aiutarti.
Potresti anche voler dare un'occhiata alla sezione di trasposizione nel manuale di Emacs. Essenzialmente:
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).
Per questo utilizzo il pacchetto smart-shift (nel Melpa). Per impostazione predefinita, si riassocia C-C <arrow>per spostare una linea o una regione. Si sposta orizzontalmente di una quantità specifica della modalità principale (ad esempio, offset di base c o offset di rientro di python). Funziona anche sulle regioni.
;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
(global-smart-shift-mode 1))