Loading ...
Sorry, an error occurred while loading the content.
 

Navigating completion menu with the space bar

Expand Messages
  • Daniel P. Wright
    Hello, short version When using inoremap , does vim throw away some part of state that is kept when using a normal inoremap? Calling an
    Message 1 of 2 , Dec 12, 2012
      Hello,

      short version>>>

      When using inoremap <expr>, does vim throw away some part of state that
      is kept when using a normal inoremap? Calling an <expr> function which
      returns <C-x><C-n> results in different behaviour to doing a plain
      inoremap to <C-x><C-n>.



      full description>>>

      I am writing a script for Japanese input in vim, making use of the
      completion functionality so that I can select appropriate kanji from a
      vim menu rather than using my OS-wide IME. My approach has been as
      follows:

      1. Simple transliteration of roman characters to kana (Japanese
      phonetic characters) within vimscript
      2. Write a completion function to take the kana input and return
      a list of valid kanji utilising tools external to vim.
      3. Override keymappings to be able to make use of the above
      functionality naturally:
      (i) Hook into CursorMovedI to do the kana transliteration
      (ii) inoremap the <space> and <cr> keys to bring up the menu
      and select a kanji.

      This is modelled on most normal OS-wide IMEs, which all work pretty much
      as described above: you type in the text, it is transliterated into kana
      as you type, and then on pressing the space bar a menu comes up offering
      you options. You can navigate this menu by pressing space repeatedly,
      and select an option by pressing return. I would like to replicate this
      functionality in vim.

      My trouble is in step 3(ii). I am using the user completefunc, and if I
      simply press <C-x><C-u> as usual the kanji options come up and I can
      navigate them with <C-x><C-p>, <C-x><C-n>, and <C-x><C-u> as usual.
      However when trying to remap this functionality to <space> and <cr> vim
      exhibits strange behaviour while attempting to navigate the menu, as if
      it's regenerating the menu every time rather than simply navigating the
      existing menu.

      My mapping is as follows:

      inoremap <buffer> <expr> <space> vime#handle_input("\<space>")
      inoremap <buffer> <expr> <cr> vime#handle_input("\<cr>")

      (As you can see, I'm passing the key pressed as a parameter. The
      documentation says that I should be able to read that from v:char, but
      when I tried to do that it returned empty)

      The handle_input function takes the key pressed and the current state of
      the IME and uses it to determine what to do, returning the appropriate
      keystrokes. It is implemented as follows:

      function! vime#handle_input(input)
      let current_pos = getpos('.')
      let current_col = current_pos[2]

      if a:input == "\<cr>"
      if pumvisible() " 3. Accept selection and close menu
      echom "Menu up! Returning accept"
      call vime#reset_startpoints()
      return "\<C-x>\<C-y>"
      endif
      elseif a:input == "\<space>"
      if pumvisible() " 2. Select next entry in menu
      echom "Menu up! Returning next"
      return "\<C-x>\<C-n>"
      elseif current_col > g:kanji_start_point " 1. Launch menu
      echom "Menu not up! Opening menu"
      return "\<C-x>\<C-u>"
      endif
      endif

      return a:input
      endfunction

      The cases marked 1 and 3 above seem to work fine: I type a word, press
      space, and the menu appears (case 1). If I press return at that point,
      the word is accepted, and the IME starts tracking the next word (case
      3). If I press space AGAIN, however, the menu is regenerated using the
      currently selected word as its input. As well as that, the output from
      :messages includes the line "Scanning tags.", which I am not printing.

      My guess is that it is throwing away the current menu before doing the
      <C-x><C-n> I'm returning, so that those keypresses then get interpreted
      as if I had entered them outside of the context of there being an open
      menu (as in :help i_CTRL-X_CTRL-N).

      If I type <C-x><C-n> myself after pressing <space> the first time, it
      works fine, so I think the problem is something to do either with the
      remapping or the fact that I'm using an <expr> function to do it.

      Any pointers would be very much appreciated!

      -Dani.

      --
      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
    • Daniel P. Wright
      Daniel P. Wright (12月12日(水)) ... I think I must have been tired yesterday. Today I made a simpler test case literally comparing a plain inoremap
      Message 2 of 2 , Dec 12, 2012
        Daniel P. Wright (12月12日(水)) >>
        > Hello,
        >
        > short version>>>
        >
        > When using inoremap <expr>, does vim throw away some part of state that
        > is kept when using a normal inoremap? Calling an <expr> function which
        > returns <C-x><C-n> results in different behaviour to doing a plain
        > inoremap to <C-x><C-n>.
        >

        I think I must have been tired yesterday. Today I made a simpler test
        case literally comparing a plain inoremap to <C-x><C-n> with an <expr>
        map calling a function which returns it, and found that actually they're
        exactly the same, so what I've written above is wrong.

        The real problem was that <C-x><C-n> is the wrong sequence of keystrokes
        to select the next item in the menu! The correct sequence is of course
        just <C-n>.

        Apologies for the noise!

        -Dani.

        --
        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
      Your message has been successfully submitted and would be delivered to recipients shortly.