martanne / vis

A vi-like editor based on Plan 9's structural regular expressions
Other
4.2k stars 258 forks source link

Sam's m (move) and t (copy) commands #954

Open acidrums4 opened 3 years ago

acidrums4 commented 3 years ago

I'd like vis to support sam-like m and t commands[1] (maybe even s?), for moving and yanking text, respectively. This makes some yank/move text workflows easier as the user does not need to place the cursor where the text they want to move/yank is, but just give its address and the address they want that text to be yanked/moved to.

Vim supports this commands too, and there's a screencast that illustrates better what I'm speaking of[2].

[1] http://doc.cat-v.org/plan_9/4th_edition/papers/sam/ [2] http://vimcasts.org/episodes/long-range-line-duplication/

honestSalami commented 2 years ago

I agree with this, especially because it would make something like ,x/Emacs/+- t 0 possible. Right now, I cannot find a way to copy all line matches to a single unified location. Selecting all lines containing 'Emacs' and hitting y only copies the line where the main cursor is located, not all the lines as I would have assumed.

Even though the functionality looks like is already implemented with vim normal mode commands, the multiple cursor feature is not fulfilling its full potential with the current bindings from vim.

ninewise commented 2 years ago

y does copy each selection, @honestSalami, but when pasting each cursor pastes only the corresponding copy. As example, create a file with { yes | head -5; seq 1 5; } > testfile. Use :x v/y/<Enter><Esc>dd to get a cursor on each number and cut the line. Use :x<Enter><Esc>p to paste each number after the corresponding y's.

Of course, for situations where you'd move each line containing a pattern to the front of a file, a t would be much easier than cutting them, creating "enough" cursors at the start, and pasting.

honestSalami commented 2 years ago

@ninewise thank you for the tip! That each selection es held on the cursor that copied it makes sense, since I was trying to yank it, then escaping to move to the end of the file, and then pasting. Escaping would remove all the cursors, thus only the selection of the primary cursor would get pasted.

honestSalami commented 2 years ago

I found a way to implement my personal usecase:

:,x/a/ > cat >> filename
:e

thoug it requires the current file to have a name, and it can only append things at the end of the file, and they all get bundled up in a single line.

Another useful thing would be to manipulate the selection as a stream without modifying the original file. Since I am interacting with the cli a lot, cleaning the data for an external command migth be useful. but thats a story for another day XD

zsugabubus commented 1 year ago

Copy and move can be emulated with the help of registers:

:x/.*\n/ g/a/ 42 i/&/
:x/.*\n/ g/a/ { d $ i/&/ }
:x/.*Emacs.*\n/ 0 i/&/
:x/.*Emacs.*\n/ { d 0 i/&/ }

(I do not know if its a bug or the correct behavior but it seems like plain x does not update "&, so you have to type a bit more.)