Problem with feedkeys()

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with feedkeys()

Holger Rapp
Hi,

I am the developer of UltiSnips, the ultimate snippet solution for
vim[1]. A user of mine has reported a bug [2] that is hard for me to
fix and I am in search of inspiration on this list.

UltiSnips selects part of text by using feedkeys(). For example to
select two lines for overwriting in insert mode, we would use
something like
  feedkeys("\<Esc>v2j\<c-g>")
The user now has a langmap set, which remaps the j key and the whole
scheme falls down. My idea was now to cache the content of the langmap
option and restore it after the feedkeys() call. Unfortunately, the
feedkeys() keys are not evaluated till after my script has finished
running; at this point in time, the langmap is already restored and
therefore the feedkeys call does not work out.

Is there a way to force the evaluation of the keyboard buffer? Or is
there maybe a clever autocommand in which I can restore the contents
of langmap, so that it is not set after my scripts run (so that
feedkeys() does the right thing) but it is reset as soon as the user
needs it.

[1] http://www.vim.org/scripts/script.php?script_id=2715
[2] https://bugs.launchpad.net/ultisnips/+bug/501727

Thanks for your help!
Holger

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Nikolay Aleksandrovich Pavlov
Ответ на сообщение «Problem with feedkeys()»,
присланное в 18:33:47 17 августа 2010, Вторник,
отправитель SirVer:

Maybe you should try using ``normal!'' command? Or feedkeys with string "n" as a
second argument: I do not know how it interacts with langmap, but it does not
let remapping fed keys by user maps.

Текст сообщения:

> Hi,
>
> I am the developer of UltiSnips, the ultimate snippet solution for
> vim[1]. A user of mine has reported a bug [2] that is hard for me to
> fix and I am in search of inspiration on this list.
>
> UltiSnips selects part of text by using feedkeys(). For example to
> select two lines for overwriting in insert mode, we would use
> something like
>   feedkeys("\<Esc>v2j\<c-g>")
> The user now has a langmap set, which remaps the j key and the whole
> scheme falls down. My idea was now to cache the content of the langmap
> option and restore it after the feedkeys() call. Unfortunately, the
> feedkeys() keys are not evaluated till after my script has finished
> running; at this point in time, the langmap is already restored and
> therefore the feedkeys call does not work out.
>
> Is there a way to force the evaluation of the keyboard buffer? Or is
> there maybe a clever autocommand in which I can restore the contents
> of langmap, so that it is not set after my scripts run (so that
> feedkeys() does the right thing) but it is reset as soon as the user
> needs it.
>
> [1] http://www.vim.org/scripts/script.php?script_id=2715
> [2] https://bugs.launchpad.net/ultisnips/+bug/501727
>
> Thanks for your help!
> Holger

signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Christian Brabandt
In reply to this post by Holger Rapp
Hi SirVer!

On Di, 17 Aug 2010, SirVer wrote:

> I am the developer of UltiSnips, the ultimate snippet solution for
> vim[1]. A user of mine has reported a bug [2] that is hard for me to
> fix and I am in search of inspiration on this list.
>
> UltiSnips selects part of text by using feedkeys(). For example to
> select two lines for overwriting in insert mode, we would use
> something like
>   feedkeys("\<Esc>v2j\<c-g>")
> The user now has a langmap set, which remaps the j key and the whole
> scheme falls down. My idea was now to cache the content of the langmap
> option and restore it after the feedkeys() call. Unfortunately, the
> feedkeys() keys are not evaluated till after my script has finished
> running; at this point in time, the langmap is already restored and
> therefore the feedkeys call does not work out.
>
> Is there a way to force the evaluation of the keyboard buffer? Or is
> there maybe a clever autocommand in which I can restore the contents
> of langmap, so that it is not set after my scripts run (so that
> feedkeys() does the right thing) but it is reset as soon as the user
> needs it.
>
> [1] http://www.vim.org/scripts/script.php?script_id=2715
> [2] https://bugs.launchpad.net/ultisnips/+bug/501727

Have you played with the different second arguments for feedkeys?

regards,
Christian

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Andy Wokula
In reply to this post by Holger Rapp
Am 17.08.2010 16:33, schrieb SirVer:

> Hi,
>
> I am the developer of UltiSnips, the ultimate snippet solution for
> vim[1]. A user of mine has reported a bug [2] that is hard for me to
> fix and I am in search of inspiration on this list.
>
> UltiSnips selects part of text by using feedkeys(). For example to
> select two lines for overwriting in insert mode, we would use
> something like
>    feedkeys("\<Esc>v2j\<c-g>")
> The user now has a langmap set, which remaps the j key and the whole
> scheme falls down. My idea was now to cache the content of the langmap
> option and restore it after the feedkeys() call. Unfortunately, the
> feedkeys() keys are not evaluated till after my script has finished
> running; at this point in time, the langmap is already restored and
> therefore the feedkeys call does not work out.
>
> Is there a way to force the evaluation of the keyboard buffer? Or is
> there maybe a clever autocommand in which I can restore the contents
> of langmap, so that it is not set after my scripts run (so that
> feedkeys() does the right thing) but it is reset as soon as the user
> needs it.
>
> [1] http://www.vim.org/scripts/script.php?script_id=2715
> [2] https://bugs.launchpad.net/ultisnips/+bug/501727

feedkeys() with "n" argument doesn't help:
     :set langmap=jG
     :call feedkeys("j", "n")


Here is an attempt with <script> mappings.
The following example doesn't use feedkeys() at all.
I guess the tricky part will be to make sure that RestoreOptions()
is executed always -- for example, it will not be executed when
the InsertActions produce a Beep!.


set langmap=jG

inoremap <script>  <Tab>  <C-R>=ProcessTab()<CR><SID>go!!

noremap!  <SID>post  <C-R>=RestoreOptions()<CR>
noremap   <SID>post  :<C-U>call RestoreOptions()<CR>

func! MapInsertActions(rhs)
     exec "inoremap <script> <SID>go!!" a:rhs."<SID>post"
endfunc

" --------------------------------------------------
" could be a 2nd script
func! ProcessTab()
     call SaveOptions(['lmap'])
     set langmap=
     call MapInsertActions("<Esc>v2j<C-G>")
     return ""
endfunc

" --------------------------------------------------
" could be a 3rd script
let g:saved_options = []

func! SaveOptions(opt_list)
     let g:saved_options = reverse(
         \ map(copy(a:opt_list), '[v:val, eval("&". v:val)]'))
endfunc

func! RestoreOptions()
     for [optname, value] in g:saved_options
         exec 'let &l:'.optname "= value"
     endfor
     let g:saved_options = []
endfunc

--
Andy

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Holger Rapp
Thanks for all the replies!

I have tried all the 'mode' options to feedkeys and as mentioned by
Andy, the do not work. I cannot use the normal command as the last
keystroke <c-g> (switching from visual to select mode) is not executed
then. I can also not mix normal and feedkeys() because of the
ordering, feedkeys are always executed at the very end.

Andy, your solution is something i thought off, but it seems quite
fragile. I am now trying to parse and reverse the langmap for snippet
execution. Feels less then ideal and especially feels like fighting
vim, not like cruising with it :(

Thanks for your support, all!

Holger

On 17 Aug., 21:18, Andy Wokula <[hidden email]> wrote:

> Am 17.08.2010 16:33, schrieb SirVer:
>
>
>
>
>
> > Hi,
>
> > I am the developer of UltiSnips, the ultimate snippet solution for
> > vim[1]. A user of mine has reported a bug [2] that is hard for me to
> > fix and I am in search of inspiration on this list.
>
> > UltiSnips selects part of text by using feedkeys(). For example to
> > select two lines for overwriting in insert mode, we would use
> > something like
> >    feedkeys("\<Esc>v2j\<c-g>")
> > The user now has a langmap set, which remaps the j key and the whole
> > scheme falls down. My idea was now to cache the content of the langmap
> > option and restore it after the feedkeys() call. Unfortunately, the
> > feedkeys() keys are not evaluated till after my script has finished
> > running; at this point in time, the langmap is already restored and
> > therefore the feedkeys call does not work out.
>
> > Is there a way to force the evaluation of the keyboard buffer? Or is
> > there maybe a clever autocommand in which I can restore the contents
> > of langmap, so that it is not set after my scripts run (so that
> > feedkeys() does the right thing) but it is reset as soon as the user
> > needs it.
>
> > [1]http://www.vim.org/scripts/script.php?script_id=2715
> > [2]https://bugs.launchpad.net/ultisnips/+bug/501727
>
> feedkeys() with "n" argument doesn't help:
>      :set langmap=jG
>      :call feedkeys("j", "n")
>
> Here is an attempt with <script> mappings.
> The following example doesn't use feedkeys() at all.
> I guess the tricky part will be to make sure that RestoreOptions()
> is executed always -- for example, it will not be executed when
> the InsertActions produce a Beep!.
>
> set langmap=jG
>
> inoremap <script>  <Tab>  <C-R>=ProcessTab()<CR><SID>go!!
>
> noremap!  <SID>post  <C-R>=RestoreOptions()<CR>
> noremap   <SID>post  :<C-U>call RestoreOptions()<CR>
>
> func! MapInsertActions(rhs)
>      exec "inoremap <script> <SID>go!!" a:rhs."<SID>post"
> endfunc
>
> " --------------------------------------------------
> " could be a 2nd script
> func! ProcessTab()
>      call SaveOptions(['lmap'])
>      set langmap=
>      call MapInsertActions("<Esc>v2j<C-G>")
>      return ""
> endfunc
>
> " --------------------------------------------------
> " could be a 3rd script
> let g:saved_options = []
>
> func! SaveOptions(opt_list)
>      let g:saved_options = reverse(
>          \ map(copy(a:opt_list), '[v:val, eval("&". v:val)]'))
> endfunc
>
> func! RestoreOptions()
>      for [optname, value] in g:saved_options
>          exec 'let &l:'.optname "= value"
>      endfor
>      let g:saved_options = []
> endfunc
>
> --
> Andy

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Andy Wokula
In reply to this post by Andy Wokula
Am 17.08.2010 21:18, schrieb Andy Wokula:

> Am 17.08.2010 16:33, schrieb SirVer:
>> Hi,
>>
>> I am the developer of UltiSnips, the ultimate snippet solution for
>> vim[1]. A user of mine has reported a bug [2] that is hard for me to
>> fix and I am in search of inspiration on this list.
>>
>> UltiSnips selects part of text by using feedkeys(). For example to
>> select two lines for overwriting in insert mode, we would use
>> something like
>> feedkeys("\<Esc>v2j\<c-g>")
>> The user now has a langmap set, which remaps the j key and the whole
>> scheme falls down. My idea was now to cache the content of the langmap
>> option and restore it after the feedkeys() call. Unfortunately, the
>> feedkeys() keys are not evaluated till after my script has finished
>> running; at this point in time, the langmap is already restored and
>> therefore the feedkeys call does not work out.
>>
>> Is there a way to force the evaluation of the keyboard buffer? Or is
>> there maybe a clever autocommand in which I can restore the contents
>> of langmap, so that it is not set after my scripts run (so that
>> feedkeys() does the right thing) but it is reset as soon as the user
>> needs it.
>>
>> [1] http://www.vim.org/scripts/script.php?script_id=2715
>> [2] https://bugs.launchpad.net/ultisnips/+bug/501727

There is an item in the todo list:

     :h todo

| Problem with 'langmap' being used on the rhs of a mapping. (Nikolai Weibull,
| 2008 May 14)

http://groups.google.com/group/vim_dev/browse_thread/thread/c2ba145ae44f4a40/6131f3a991847615

> feedkeys() with "n" argument doesn't help:
> :set langmap=jG
> :call feedkeys("j", "n")
>
>
> Here is an attempt with <script> mappings.
> The following example doesn't use feedkeys() at all.
> I guess the tricky part will be to make sure that RestoreOptions()
> is executed always -- for example, it will not be executed when
> the InsertActions produce a Beep!.
>
>
> set langmap=jG
>
> inoremap <script> <Tab> <C-R>=ProcessTab()<CR><SID>go!!
>
> noremap! <SID>post <C-R>=RestoreOptions()<CR>
> noremap <SID>post :<C-U>call RestoreOptions()<CR>
>
> func! MapInsertActions(rhs)
> exec "inoremap <script> <SID>go!!" a:rhs."<SID>post"
> endfunc
>
> " --------------------------------------------------
> " could be a 2nd script
> func! ProcessTab()
> call SaveOptions(['lmap'])
> set langmap=
> call MapInsertActions("<Esc>v2j<C-G>")
> return ""
> endfunc
>
> " --------------------------------------------------
> " could be a 3rd script
> let g:saved_options = []
>
> func! SaveOptions(opt_list)
> let g:saved_options = reverse(
> \ map(copy(a:opt_list), '[v:val, eval("&". v:val)]'))
> endfunc
>
> func! RestoreOptions()
> for [optname, value] in g:saved_options
> exec 'let &l:'.optname "= value"
> endfor
> let g:saved_options = []
> endfunc

To restore options, you could also use

    feedkeys("\<Esc>v2j\<c-g>\<Plug>(UltisnipRestore)")

where <Plug>(UltisnipRestore) restores the options, but then the whole
sequence must be kept remappable (feedkeys() does not allow mixing of
remappable and non-remappable parts).

Sooner or later you will not want to allow remapping for
"\<Esc>v2j\<c-g>".  That's why I posted something that prepares for that
case.

An alternative is to exclusively use <Plug> mappings:
    inoremap <Plug>(UltisnipDoThat) <Esc>v2j<c-g>

    call feedkeys("\<Plug>(UltisnipDoThat)\<Plug>(UltisnipRestore)")

--
Andy

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Holger Rapp
In reply to this post by Holger Rapp
Just a quick follwup:

I tried Andy last suggestion using

    call feedkeys("\<Plug>(UltisnipDoThat)\<Plug>(UltisnipRestore)")

and using inoremap <script> to define my movement commands each time
before it should be executed. This didn't work out as vim doesn't
ignore the langmap even with inoremap and happily keeps remapping the
keys. I now swallowed the pill and parsed and reversed the langmap as
long as it is possible, that is something like this:

langmap=dj,jd

is invertable. But something like

langmap=dj

is obviously not invertable. So as long as all you want is swapping
some keys around, ultisnip will cope; if you overwrite some key
mappings, ultisnips will choke.

Thanks again for all the help!!

Holger

On Aug 18, 9:53 am, SirVer <[hidden email]> wrote:

> Thanks for all the replies!
>
> I have tried all the 'mode' options to feedkeys and as mentioned by
> Andy, the do not work. I cannot use the normal command as the last
> keystroke <c-g> (switching from visual to select mode) is not executed
> then. I can also not mix normal and feedkeys() because of the
> ordering, feedkeys are always executed at the very end.
>
> Andy, your solution is something i thought off, but it seems quite
> fragile. I am now trying to parse and reverse the langmap for snippet
> execution. Feels less then ideal and especially feels like fighting
> vim, not like cruising with it :(
>
> Thanks for your support, all!
>
> Holger
>
> On 17 Aug., 21:18, Andy Wokula <[hidden email]> wrote:
>
>
>
> > Am 17.08.2010 16:33, schrieb SirVer:
>
> > > Hi,
>
> > > I am the developer of UltiSnips, the ultimate snippet solution for
> > > vim[1]. A user of mine has reported a bug [2] that is hard for me to
> > > fix and I am in search of inspiration on this list.
>
> > > UltiSnips selects part of text by using feedkeys(). For example to
> > > select two lines for overwriting in insert mode, we would use
> > > something like
> > >    feedkeys("\<Esc>v2j\<c-g>")
> > > The user now has a langmap set, which remaps the j key and the whole
> > > scheme falls down. My idea was now to cache the content of the langmap
> > > option and restore it after the feedkeys() call. Unfortunately, the
> > > feedkeys() keys are not evaluated till after my script has finished
> > > running; at this point in time, the langmap is already restored and
> > > therefore the feedkeys call does not work out.
>
> > > Is there a way to force the evaluation of the keyboard buffer? Or is
> > > there maybe a clever autocommand in which I can restore the contents
> > > of langmap, so that it is not set after my scripts run (so that
> > > feedkeys() does the right thing) but it is reset as soon as the user
> > > needs it.
>
> > > [1]http://www.vim.org/scripts/script.php?script_id=2715
> > > [2]https://bugs.launchpad.net/ultisnips/+bug/501727
>
> > feedkeys() with "n" argument doesn't help:
> >      :set langmap=jG
> >      :call feedkeys("j", "n")
>
> > Here is an attempt with <script> mappings.
> > The following example doesn't use feedkeys() at all.
> > I guess the tricky part will be to make sure that RestoreOptions()
> > is executed always -- for example, it will not be executed when
> > the InsertActions produce a Beep!.
>
> > set langmap=jG
>
> > inoremap <script>  <Tab>  <C-R>=ProcessTab()<CR><SID>go!!
>
> > noremap!  <SID>post  <C-R>=RestoreOptions()<CR>
> > noremap   <SID>post  :<C-U>call RestoreOptions()<CR>
>
> > func! MapInsertActions(rhs)
> >      exec "inoremap <script> <SID>go!!" a:rhs."<SID>post"
> > endfunc
>
> > " --------------------------------------------------
> > " could be a 2nd script
> > func! ProcessTab()
> >      call SaveOptions(['lmap'])
> >      set langmap=
> >      call MapInsertActions("<Esc>v2j<C-G>")
> >      return ""
> > endfunc
>
> > " --------------------------------------------------
> > " could be a 3rd script
> > let g:saved_options = []
>
> > func! SaveOptions(opt_list)
> >      let g:saved_options = reverse(
> >          \ map(copy(a:opt_list), '[v:val, eval("&". v:val)]'))
> > endfunc
>
> > func! RestoreOptions()
> >      for [optname, value] in g:saved_options
> >          exec 'let &l:'.optname "= value"
> >      endfor
> >      let g:saved_options = []
> > endfunc
>
> > --
> > Andy

--
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
Reply | Threaded
Open this post in threaded view
|

Re: Problem with feedkeys()

Andy Wokula
Am 18.08.2010 12:50, schrieb SirVer:
> Just a quick follwup:
>
> I tried Andy last suggestion using
>
>      call feedkeys("\<Plug>(UltisnipDoThat)\<Plug>(UltisnipRestore)")
>
> and using inoremap<script>  to define my movement commands each time
> before it should be executed.

This suggestion does not involve <script> mappings.  All <Plug>mappings
are mapped with :inoremap, :nnoremap, :noremap etc.  (no remapping
allowed).

You still need to "set lmap=" (somewhere in the function that calls
feedkeys()) and restore it afterwards.  "afterwards" is the time when
<Plug>(UltisnipRestore) is executed.

> This didn't work out as vim doesn't ignore the langmap even with
> inoremap

Yep, :inoremap alone doesn't solve the problem.

> and happily keeps remapping the keys. I now swallowed the pill and
> parsed and reversed the langmap as long as it is possible, that is
> something like this:
>
> langmap=dj,jd
>
> is invertable. But something like
>
> langmap=dj
>
> is obviously not invertable. So as long as all you want is swapping
> some keys around, ultisnip will cope; if you overwrite some key
> mappings, ultisnips will choke.

;-)

--
Andy

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