g@ seems to ignore user-defined motion maps

25 views
Skip to first unread message

Brett Stahlman

unread,
Jul 11, 2014, 8:18:39 AM7/11/14
to vim...@googlegroups.com, kovi...@gmail.com
Hello,
I recently noticed that Paredit's `d{motion}' map doesn't behave the way
I would expect: in particular, although `)' in normal mode jumps
correctly to the end of the current S-expression, `d)' deletes beyond
the end of the S-exp. It seems as though perhaps the `)' motion reverts
to its non-Paredit meaning (forward sentence) until after the
operatorfunc has executed. Is this by design? Hopefully not, since
users would typically expect plugin-defined mappings to work the same
with an operator as they do in normal mode.

Thanks,
Brett S.

Brett Stahlman

unread,
Jul 11, 2014, 1:04:53 PM7/11/14
to vim...@googlegroups.com, kovi...@gmail.com

Having thought about it a bit, it occurs to me that it would be very difficult for Vim's g@ implementation to treat movements accomplished via user mappings the same as built-in {motion}s. Perhaps that's why only Vim {motion}s are considered? In the case of Paredit, Tamas has graciously agreed to add explicit normal mode mappings for d), c), etc..., which is an acceptable workaround.

Thanks,
Brett S.

>
> Thanks,
> Brett S.

ZyX

unread,
Jul 11, 2014, 1:51:47 PM7/11/14
to vim...@googlegroups.com, kovi...@gmail.com
> Having thought about it a bit, it occurs to me that it would be very difficult for Vim's g@ implementation to treat movements accomplished via user mappings the same as built-in {motion}s. Perhaps that's why only Vim {motion}s are considered? In the case of Paredit, Tamas has graciously agreed to add explicit normal mode mappings for d), c), etc..., which is an acceptable workaround.

No, it is by no means different from motion support in `d` and other built-in operators. My translit3 plugin has no problems with using motion from camelcasemotion plugin and it uses `g@` under the hood. So you should search problem somewhere else.

Brett Stahlman

unread,
Jul 11, 2014, 2:54:36 PM7/11/14
to vim...@googlegroups.com, kovi...@gmail.com
On Friday, July 11, 2014 12:51:47 PM UTC-5, ZyX wrote:
> > Having thought about it a bit, it occurs to me that it would be very difficult for Vim's g@ implementation to treat movements accomplished via user mappings the same as built-in {motion}s. Perhaps that's why only Vim {motion}s are considered? In the case of Paredit, Tamas has graciously agreed to add explicit normal mode mappings for d), c), etc..., which is an acceptable workaround.
>
> No, it is by no means different from motion support in `d` and other built-in operators. My translit3 plugin has no problems with using motion from camelcasemotion plugin and it uses `g@` under the hood. So you should search problem somewhere else.

This is not what I see. Here's a test case consisting of the map-operator example from the Vim help, along with a normal mode remapping of $ to G. Hitting $ in normal mode now goes to the end of the file, but hitting <F4>$ counts only the spaces on the current line...

Brett S.

nmap <silent> <F4> :set opfunc=CountSpaces<CR>g@
vmap <silent> <F4> :<C-U>call CountSpaces(visualmode(), 1)<CR>
nmap $ G

function! CountSpaces(type, ...)
let sel_save = &selection
let &selection = "inclusive"
let reg_save = @@

if a:0 " Invoked from Visual mode, use '< and '> marks.
silent exe "normal! `<" . a:type . "`>y"
elseif a:type == 'line'
silent exe "normal! '[V']y"
elseif a:type == 'block'
silent exe "normal! `[\<C-V>`]y"
else
silent exe "normal! `[v`]y"
endif

echomsg strlen(substitute(@@, '[^ ]', '', 'g'))

let &selection = sel_save
let @@ = reg_save
endfunction


Christian Brabandt

unread,
Jul 11, 2014, 3:03:31 PM7/11/14
to vim...@googlegroups.com
Hi Brett!

On Fr, 11 Jul 2014, Brett Stahlman wrote:

> This is not what I see. Here's a test case consisting of the
> map-operator example from the Vim help, along with a normal mode
> remapping of $ to G. Hitting $ in normal mode now goes to the end of
> the file, but hitting <F4>$ counts only the spaces on the current
> line...

You are using $ in operator pending mode, so you would need an omap $ G
as well. And then it works.

Best,
Christian
--
Panischer Anruf bei der Bahndirektion:
"AUF DEM BAHNDAMM LIEGT EIN GLEIS!"
Sagt der Bahnbeamte: "Das ist auch gut so!" und hängt wieder auf.
Fünf Minuten der gleiche Anrufer: "Jetzt haben sie den almen alten
Mann übelfahlen!"

Павлов Николай Александрович

unread,
Jul 11, 2014, 3:03:55 PM7/11/14
to vim...@googlegroups.com, Brett Stahlman, kovi...@gmail.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

On July 11, 2014 10:54:36 PM GMT+03:00, Brett Stahlman <bretts...@gmail.com> wrote:
>On Friday, July 11, 2014 12:51:47 PM UTC-5, ZyX wrote:
>> > Having thought about it a bit, it occurs to me that it would be
>very difficult for Vim's g@ implementation to treat movements
>accomplished via user mappings the same as built-in {motion}s. Perhaps
>that's why only Vim {motion}s are considered? In the case of Paredit,
>Tamas has graciously agreed to add explicit normal mode mappings for
>d), c), etc..., which is an acceptable workaround.
>>
>> No, it is by no means different from motion support in `d` and other
>built-in operators. My translit3 plugin has no problems with using
>motion from camelcasemotion plugin and it uses `g@` under the hood. So
>you should search problem somewhere else.
>
>This is not what I see. Here's a test case consisting of the
>map-operator example from the Vim help, along with a normal mode
>remapping of $ to G. Hitting $ in normal mode now goes to the end of
>the file, but hitting <F4>$ counts only the spaces on the current
>line...
>
>Brett S.
>
>nmap <silent> <F4> :set opfunc=CountSpaces<CR>g@
>vmap <silent> <F4> :<C-U>call CountSpaces(visualmode(), 1)<CR>
>nmap $ G

Sure. :nmap cannot define motions (and, by the way, *never* use :nmap, :vmap, etc without nore unless you absolutely have to).

You must define at least three mappings:

nnoremap $ G
xnoremap $ G
onoremap $ G

. Last one does work for g@.

Some simple mappings will work if you use

noremap $ G

, but this will redefine $ in select mode as well. Most of time nobody cares about select mode though.


To say that motions do not work *you must define motions*. You did not do this.

>
>function! CountSpaces(type, ...)
> let sel_save = &selection
> let &selection = "inclusive"
> let reg_save = @@
>
> if a:0 " Invoked from Visual mode, use '< and '> marks.
> silent exe "normal! `<" . a:type . "`>y"
> elseif a:type == 'line'
> silent exe "normal! '[V']y"
> elseif a:type == 'block'
> silent exe "normal! `[\<C-V>`]y"
> else
> silent exe "normal! `[v`]y"
> endif
>
> echomsg strlen(substitute(@@, '[^ ]', '', 'g'))
>
> let &selection = sel_save
> let @@ = reg_save
>endfunction

-----BEGIN PGP SIGNATURE-----
Version: APG v1.1.1

iQI1BAEBCgAfBQJTwDUMGBxaeVggPHp5eC52aW1AZ21haWwuY29tPgAKCRCf3UKj
HhHSvmXiD/9G/OSqXBEzaqNK0t6tU4RC3UROnpUgMZdtPRbb2fAvBLO7WU02EJM2
+Ox7rFF6r+YyDjA0IX/Sn6HNdAs0tC7i0t9H+JbqsfHZADwaCCaxeWBYhKKYI1ND
YbUVWnIHUMjCrLv5l7dR9wG2ICLPpanlffxXKEVocstE6OevmIsLnv/C2ly1W1/k
eHWrVKj1MYBpNB/KwDIzRkP6CliWQch38YrguHaf6uRW+l4puXZANGN4JU77IPrp
QnvEvNyp684f+g0IIQXo+oFesZgk+vUYAB0bmPBMjuPVB/gmfS9iloSdaacf3/Pi
u+oXJQ6azH33f6seDk0H/ZQDj+oam8aBWFEIAREPY6NRB9ENoLwJgs82vDlNAyOl
1BuDh62+6tc9FB89B0SQDiJhWKM2SDjM8BH9q+Sd2hjZO/UsHD6IBpGBO8PVJnnX
DaoPbbH8yT09ars1BYSHiPu5yWARzRlWca5e3wiEnNjH0q+6WhiwKrrf9y/rvVO1
w5iNTUR4wVv2VgdwU6G4Tq3AMZw0CKcnYJ8GlhM+7OFMi9hQOfDYT84z/az8NTAa
NnWWBpQdW7ME1eE/nJiw8l5aUjOW4igj/BwDEXfyEZ4ATYSCJEm5l6Gv22s3sP0j
alZ/uHMaKavGuj792vI3yWYaycNawnuFfSY3cnQqyENJFFuwnn2TDg==
=KiCh
-----END PGP SIGNATURE-----

Brett Stahlman

unread,
Jul 11, 2014, 3:11:13 PM7/11/14
to vim...@googlegroups.com

Ah. Of course! Makes perfect sense now.
Thanks,
Brett S.

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to a topic in the Google Groups "vim_use" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vim_use/jajT77b2cVk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vim_use+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brett Stahlman

unread,
Jul 11, 2014, 4:24:45 PM7/11/14
to vim...@googlegroups.com
On Friday, July 11, 2014 2:03:31 PM UTC-5, Christian Brabandt wrote:
> Hi Brett!
>
>
>
> On Fr, 11 Jul 2014, Brett Stahlman wrote:
>
>
>
> > This is not what I see. Here's a test case consisting of the
>
> > map-operator example from the Vim help, along with a normal mode
>
> > remapping of $ to G. Hitting $ in normal mode now goes to the end of
>
> > the file, but hitting <F4>$ counts only the spaces on the current
>
> > line...
>
>
>
> You are using $ in operator pending mode, so you would need an omap $ G
>
> as well. And then it works.

Not sure this solves the problem for paredit though... The simple example I gave maps a Vim {motion} to another Vim {motion} ($ to G), but paredit is using a function to accomplish the motion. If I replace omap $ G with the following...

omap $ :call cursor(line('$'))<CR>

...it doesn't seem to work.

Thanks,
Brett S.

Brett Stahlman

unread,
Jul 11, 2014, 6:39:57 PM7/11/14
to vim...@googlegroups.com
On Friday, July 11, 2014 3:24:45 PM UTC-5, Brett Stahlman wrote:
> On Friday, July 11, 2014 2:03:31 PM UTC-5, Christian Brabandt wrote:
>
> > Hi Brett!
>
> >
>
> >
>
> >
>
> > On Fr, 11 Jul 2014, Brett Stahlman wrote:
>
> >
>
> >
>
> >
>
> > > This is not what I see. Here's a test case consisting of the
>
> >
>
> > > map-operator example from the Vim help, along with a normal mode
>
> >
>
> > > remapping of $ to G. Hitting $ in normal mode now goes to the end of
>
> >
>
> > > the file, but hitting <F4>$ counts only the spaces on the current
>
> >
>
> > > line...
>
> >
>
> >
>
> >
>
> > You are using $ in operator pending mode, so you would need an omap $ G
>
> >
>
> > as well. And then it works.
>
>
>
> Not sure this solves the problem for paredit though... The simple example I gave maps a Vim {motion} to another Vim {motion} ($ to G), but paredit is using a function to accomplish the motion. If I replace omap $ G with the following...
>
>
>
> omap $ :call cursor(line('$'))<CR>
>
>
>
> ...it doesn't seem to work.

Ooops! I thought the column argument to cursor was optional - it's not... When I changed the call to cursor(line('$'), 1), things worked as expected. Sorry for the confusion...

Brett S.
Reply all
Reply to author
Forward
0 new messages