95 votes

Déplacer une ligne/région vers le haut et le bas dans emacs

Quel est le moyen le plus simple de déplacer une région ou une ligne sélectionnée (s'il n'y a pas de sélection) vers le haut ou le bas dans emacs ? Je cherche la même fonctionnalité que dans Eclipse (limité à M-up, M-down).

2 votes

Je suis presque sûr que l'idiome est de tuer ce que vous voulez déplacer, d'utiliser les fonctions de navigation habituelles (y compris isearch, etc.) pour déplacer le point où vous voulez que le code soit, puis de tirer. Il y a une pile de kills, rappelez-vous, donc vous n'avez même pas besoin de trouver l'emplacement immédiatement ; vous pouvez rassembler d'autres morceaux pour les tirer plus tard. Personnellement, en tant que gros utilisateur d'Emacs, je ne peux pas imaginer une situation où je préférerais déplacer manuellement une seule ligne vers le haut ou vers le bas. Ce ne serait tout simplement pas utile.

9 votes

@jrockway : merci pour votre commentaire. Je pense que chacun a sa propre façon de faire les choses. Je travaille beaucoup avec eclipse et je suis très habitué à déplacer des lignes/régions. L'un des grands avantages d'avoir emacs très extensible est que cette fonctionnalité peut être facilement ajoutée.

4 votes

Convenu. Je souhaite souvent déplacer des lignes de haut en bas comme vous le décrivez, que je sois ou non dans un éditeur qui le supporte. Ou, d'ailleurs, que je travaille ou non sur du code. Word prend en charge cette fonction (par paragraphe) avec Alt+Shift+Up et Down, et je l'utilise dans mes éditeurs chaque fois que je le peux.

55voto

sanityinc Points 9156

Mise à jour : Installer le move-text paquet de Marmalade ou MELPA pour obtenir le code suivant.

Voici ce que j'utilise, qui fonctionne à la fois sur les régions et les lignes individuelles :

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

1 votes

J'ai ajouté ceci à EmacsWiki pour vous, c'est ici : emacswiki.org/emacs/MoveText

0 votes

Merci ! Je pense que ce code était déjà là ( emacswiki.org/emacs/basic-edit-toolkit.el ) mais cette nouvelle page sera plus facile à trouver pour les gens.

0 votes

Ahh, cool je n'avais pas vu ça avant, on dirait que basic-edit-toolkit aurait besoin d'un nettoyage.

53voto

Martin Wickman Points 9628

Une ligne peut être déplacée en utilisant lignes de transposition lié à C-x C-t . Je ne sais pas pour les régions, par contre.

J'ai trouvé ce elisp snippet qui fait ce que vous voulez, sauf que vous devez changer les liens.

(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 votes

Merci pour cet extrait. C'est exactement ce que je cherchais !

0 votes

Il y a un petit problème avec cette solution, et celle presque identique postée par @sanityinc : si j'utilise le raccourci défini pour déplacer une région vers le haut et/ou vers le bas, puis que j'utilise immédiatement le raccourci pour annuler (C-_ par défaut), la région disparaît simplement, et le message "Undo in region !" est affiché dans la zone d'écho. Une autre commande d'annulation donne le message "Aucune autre information d'annulation pour la région". Toutefois, si je déplace le curseur, puis que je commande l'annulation, l'annulation recommence à fonctionner. Une irritation relativement mineure, mais toutes les autres commandes Emacs peuvent être annulées immédiatement sans avoir recours à une astuce.

3 votes

C'est exactement la bonne manière de le faire. La ligne de transposition par défaut dans Emacs n'est PAS une fonctionnalité correcte puisque le curseur se déplace à la ligne suivante après la transposition, ce qui rend difficile la répétition étape par étape.

39voto

Vous devriez essayer drag-stuff !

Il fonctionne exactement comme eclipse Alt + Up / Down pour les lignes individuelles, ainsi que pour les lignes de régions sélectionnées !

En plus de cela, il vous permet de déplacer les mots avec Alt + Left / Right
C'est exactement ce que vous recherchez ! Et il est même disponible auprès du Dépôt ELPA !

Les autres solutions n'ont jamais fonctionné pour moi. Certaines d'entre elles étaient boguées (transposer des lignes tout en changeant leur ordre, wtf ?) et certaines déplaçaient exactement la région sélectionnée, laissant les parties non sélectionnées des lignes sur leurs positions. Mais drag-stuff fonctionne exactement comme dans eclipse !

Et bien plus encore ! Vous pouvez essayer de sélectionner une région et d'utiliser Alt + Left / Right ! Ceci transposera la région sélectionnée d'un caractère vers la gauche ou la droite. Incroyable !

Pour l'activer globalement, il suffit d'exécuter ceci :

(drag-stuff-global-mode)

0 votes

Il faut vraiment que les mouvements à gauche et à droite soient optionnels, car ils remplacent le keymap par défaut d'emacs.

0 votes

@Slomojo peut-être ! Pourquoi ne pas suggérer cela sur emacswiki ? :)

1 votes

J'avais l'habitude d'utiliser ça, j'utilise smart-shift maintenant. J'aime bien qu'il DWIM pour le mouvement horizontal.

13voto

Bozhidar Batsov Points 23298

J'ai écrit quelques fonctions interactives pour déplacer des lignes vers le haut/bas :

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

Les combinaisons de touches sont du style IntelliJ IDEA, mais vous pouvez utiliser ce que vous voulez. Je devrais probablement implémenter quelques fonctions qui opèrent sur les régions aussi bien.

4voto

Manuel Points 31

Il y a une entrée dans le wiki d'emacs juste pour cela :

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

Pour les régions en mouvement :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X