Open sassanh opened 8 years ago
You're right this is a bug. I've reproduced this. Apparently, when vim does a motion over a multi-line block, if nothing else is on the line, then it selects the EOL character as well.
No vim doesn't do that, select a line in visual mode since beginning to the end excluding eol, then press d, it won't remove the eol and there'll be an empty line afterwards. It seems to be more complicated.
It seems to happen only for dat
, I tried to delete a single word in a line that contains only that single word with daw
and it didn't delete eol and kept an empty line there. but dat
removes empty lines.
What about something like daw that is multi-line other than dat?
something like this:
Line1
(
Line2
)
Line3
then you can try da(
and ma(
same can be done with {
or "
or [
in all cases d
removes eol but m doesn't.
What does m
do internally?
can we replace these lines:
EasyClipBeforeYank
normal! gvy
normal! gv"_d
EasyClipOnYanksChanged
with these:
EasyClipBeforeYank
normal! d
(some other lines)
EasyClipOnYanksChanged
and fix registers in (some other lines)?
That code you're looking at is not the issue. That's executed in visual mode. If you want to take a look see EasyClip#Move#MoveMotion
and EasyClip#Yank#_YankLastChangedText
I see so maybe we can change these lines in EasyClip#Move#MoveMotion
:
exec "normal! gv"
exec "normal! \"_d"
to
exec "normal! d"
and then fix the registers. what do you think?
Pretty sure vimscript doesn't work like that. Nothing is selected, you have to reselect in that function using gv
I have an idea though that might work, one minute
This seems to work but there's probably some edge case where it breaks
function! EasyClip#Move#MoveMotion(type)
let oldVisualStart = getpos("'<")
let oldVisualEnd = getpos("'>")
let newType = a:type
if newType ==# 'char'
let numColumnsLastLine = col([oldVisualEnd[1], '$'])
if oldVisualStart[1] != oldVisualEnd[1] && oldVisualStart[2] == 1 && oldVisualEnd[2] == numColumnsLastLine-1
let newType = 'line'
endif
endif
call EasyClip#Yank#_YankLastChangedText(newType, s:activeRegister)
exe "keepjumps normal! `[" . (newType ==# 'line' ? 'V' : 'v')
\ . "`]\"_d"
call setpos("'<", oldVisualStart)
call setpos("'>", oldVisualEnd)
endfunction
You're right, vimscript doesn't work that way. unfortunately I can't follow it up with you cause I don't understand this code unless you describe it to me (or maybe just the idea behind it and why it may break in edge cases). If you need me to try it for few days just let me know.
Yeah, I was thinking we could both try it for a few days and just keep an eye out for incorrect behaviour
Sure, will inform you if I find anything.
OK now I got what you're trying to do, I think oldVisualStart[2] == 1
should be removed, otherwise it won't work in an indented piece of html code.
Another issue I found is that getpos("'<")
and getpos("'>")' are not returning beginning and end of current motion, instead they're returning beginning and return of last motion. For example first time I run this function,
oldVisualStartand
oldVisualEndboth will set to [0,0]. And then if I run a sequence of
mats followed by
mawit all breaks because each one influences the other one and
mats make
maws work line-wise while
maws make
mat`s work character-wise.
Let me know if it's working as expected for you (maybe it's because of some plugins I have.).
A modified version of your code is working for me:
function! EasyClip#Move#MoveMotion(type)
let oldVisualStart = getpos("'[")
let oldVisualEnd = getpos("']")
let newType = a:type
if newType ==# 'char'
let numColumnsLastLine = col([oldVisualEnd[1], '$'])
if oldVisualStart[1] != oldVisualEnd[1] && oldVisualEnd[2] == numColumnsLastLine-1
let newType = 'line'
endif
endif
call EasyClip#Yank#_YankLastChangedText(newType, s:activeRegister)
exe "keepjumps normal! `[" . (newType ==# 'line' ? 'V' : 'v')
\ . "`]\"_d"
call setpos("'<", oldVisualStart)
call setpos("'>", oldVisualEnd)
endfunction
Notice these two lines in the begining:
let oldVisualStart = getpos("'[")
let oldVisualEnd = getpos("']")
I replaced <
with [
and >
with ]
, I don't know if we should apply same change at the end of the function. I found these helpful: :help exclusive
and :help map-operator
. Specially the example in :help map-operator
.
Thanks for following up on this.
I've merged this change, but I'll leave this item open since we need to do the same fix to the EasyClip#Yank#YankMotion
and EasyClip#Substitute#SubstituteMotion
functions
Suppose that this is the situation:
when double pipe shows my curser position. If I type
mat
in normal mode I getbut if I run
dat
I'll get:mat
is behaving likevatd
notdat
.