evil icon indicating copy to clipboard operation
evil copied to clipboard

Visual modes don't work with package move-text

Open rnoennig opened this issue 4 years ago • 5 comments

Issue type

  • Bug report

Environment

Emacs version: GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.14) of 2020-03-26, modified by Debian Operating System: Ubuntu 20.04.1 LTS Evil version: Evil version evil-git-eccdcbb Evil installation type: spacemacs (version at this commit) Graphical/Terminal: Graphical Tested in a make emacs session (see CONTRIBUTING.md): Yes

Reproduction steps

  • Start Emacs
  • Add Melpa
  • package-install move-text
  • For easier testing bind Alt+Up/Dow to move-text-up or move-text-down (see below for setup statements)
  • In visual-line-mode select 1 or more lines with surrounding lines (see below for example lines)
  • Execute either command move-text-up or move-text-down

Expected behavior

  • All selected lines should move 1 line up or down
  • The selection/region should move with the lines
  • Further executed commands move-text-up or move-text-down should work as well

Actual behavior

The actual behavior differs between move-text-up and move-text-down

When using move-text-up

  • The selected lines are moved up as expected
  • The selection however doesn't move with the moved lines, but instead the line below the original selection is the sole selected line gif animation of move-text-up in visual-line-mode

When using move-text-down

  • The selected lines are moved down as expected
  • The selection however doesn't move with the moved lines, but instead the first line of the original selection is the sole selected line gif animation of move-text-down in visual-line-mode

Further notes

  • The move-text commands work as expected if you select a region by mouse-drag without using any visual-*-mode. That's why I suspect it's a bug in evil rather than in the package move-text. However the package move-text might lack "evil" support, but I couldn't find any documentation about what a package should do to be compatible with evil.
  • This bug only describes the behavior in visual-line-mode, but other visual modes are affected as well.
  • I am not familar with elisp programming but would be willing to put in some work to get this fixed, so any hints on how to debug the evil macros are welcome.

Sample lines for testing:

1 first line
2 second line
3 this line will be moved
4 this line will be moved
5 last line

Setup statements to get you up and running from make emacs:

;; load emacs 24's package system. Add MELPA repository.
(when (>= emacs-major-version 24)
  (require 'package)
  (add-to-list
   'package-archives
   ;; '("melpa" . "http://stable.melpa.org/packages/") ; many packages won't show if using stable
   '("melpa" . "https://melpa.org/packages/")
   t))
(package-initialize)
(package-refresh-contents)
(package-install 'move-text)
(global-set-key (kbd "M-<up>") 'move-text-up)
(global-set-key (kbd "M-<down>") 'move-text-down)

rnoennig avatar Dec 27 '20 11:12 rnoennig

Related: https://github.com/emacsfodder/move-text/issues/11

EDIT:

The Spacemacs-related link in the above issue provides a solution limited to moving lines in visual mode (based on the Spacemacs-specific variable vim-style-visual-line-move-text), without move-text.

This can be extended to normal mode, e.g.:

(define-key evil-visual-state-map (kbd "M-<down>") (concat ":m '>+1" (kbd "RET") "gv=gv"))
(define-key evil-visual-state-map (kbd "M-<up>")   (concat ":m '<-2" (kbd "RET") "gv=gv"))
(define-key evil-normal-state-map (kbd "M-<down>") (concat ":m +1" (kbd "RET") "=="))
(define-key evil-normal-state-map (kbd "M-<up>")   (concat ":m -2" (kbd "RET") "=="))

Supports a count and does auto-indentation (can be removed if you delete the "==" and "gv=gv" portions).

VanLaser avatar Dec 28 '20 10:12 VanLaser

First of all thanks for linking the issues, second thanks for the workaround, that's helpful. In the move-text issue another package was mentioned as alternative to move-text: drag-stuff. And drag-stuff was made evil-ready in this PR: https://github.com/rejeep/drag-stuff.el/pull/13

So it looks like move-text is just not evil compatible and I would recommend to fix the implementation in move-text.

Once there is a patch for making move-text evil-compatible, maybe it would be a good idea to provide a documentation for plugin developers. So that it's clear what caveats there are when doing text manipulation with region selection in evil.

rnoennig avatar Dec 30 '20 19:12 rnoennig

Does this do what you want? https://github.com/emacs-evil/evil-collection/blob/0112d16f08b66790aa02b061cc4755096a713ab0/modes/unimpaired/evil-collection-unimpaired.el#L140-L148

leungbk avatar Jan 04 '21 23:01 leungbk

Does this do what you want? https://github.com/emacs-evil/evil-collection/blob/0112d16f08b66790aa02b061cc4755096a713ab0/modes/unimpaired/evil-collection-unimpaired.el#L140-L148

This actually has a similar faulty behavior in my "make emacs".

I used it like this:

(package-install 'evil-collection)
(evil-collection-init 'unimpared)
(global-set-key (kbd "M-<down>") (lambda () (interactive) (evil-collection-unimpaired-move-text-down 1)))
(global-set-key (kbd "M-<up>") (lambda () (interactive) (evil-collection-unimpaired-move-text-up 1)))

The best workaround (besides delete, moving around and paste) is the spacemacs vim-style-visual-line-move-text VanLaser mentioned.

I modified move-text to behave somewhat ok when used in evil's visual mode, if you're interested: move-text issue 11

rnoennig avatar Jan 06 '21 21:01 rnoennig

If I understand this correctly there is a conceptual difference between emacs' region(point and mark) and evil's visual selection. move-text only sets the point and mark and expects that the selection is the same as the region, which doesn't seem to be the case for evil. Could there be a solution where evil automatically adjusts the visual selection when the actual region changes? Or are there cases where that's a bad idea?

rnoennig avatar Jan 07 '21 18:01 rnoennig