On Fri, 19 May 2006, Malhotra, Vijendra wrote:

> -----Original Message-----
> From: Gerald Lai [mailto:[EMAIL PROTECTED]
> Sent: Tuesday 16 May 2006 12:35
> To: Malhotra, Vijendra
> Cc: vim@vim.org
> Subject: Re: Mappings fail in gvim...
>
> On Tue, 16 May 2006, Malhotra, Vijendra wrote:
>
>> I have the following mappings that work fine on vim but don't on
>> gvim any idea why
>>
>> " Window manipulation
>> "Ctrl left == Ctrl W l
>> map ^[Oc ^Wl
>> " Ctrl left
>> map ^[Od ^Wh
>> " Ctrl+Down == Ctrl-W + j
>> map ^[Ob  ^Wj
>> " Ctrl+Up == Ctrl-W + k
>> map ^[Oa ^Wk
>
> You're mapping Vim keystrokes to shell keycodes (that aren't really
> acknowledged by GVim). A better way would be to map Vim keystrokes
> to Vim's internal representation of keycodes. On the first pass, we
> would have:
>
>   nnoremap <C-Right> <C-w>l
>   nnoremap <C-Left>  <C-w>h
>   nnoremap <C-Down>  <C-w>j
>   nnoremap <C-Up>    <C-w>k
>
>   nmap ^[Oc <C-Right>
>   nmap ^[Od <C-Left>
>   nmap ^[Ob <C-Down>
>   nmap ^[Oa <C-Up>
>
>   (should work in GVim at this point)
>
> But mapping ^[O<alphabet> will cause Vim to wait everytime you press
> Esc, because there's a possibility that an "O" followed by an
> alphabet will come after the Esc. You won't manually type that "O" +
> .., of course (but it's possible). It comes whenever you do the
> Ctrl-combination in the terminal.
>
> An improvement would be to represent the shell keycode as one of
> Vim's internal representation. Then we can use 'ttimeoutlen':
>
>   set timeout timeoutlen=1000 ttimeoutlen=100
>   set <xF1>=^[Oc <xF2>=^[Od <xF3>=^[Ob <xF4>=^[Oa
>
>   nnoremap <C-Right> <C-w>l
>   nnoremap <C-Left>  <C-w>h
>   nnoremap <C-Down>  <C-w>j
>   nnoremap <C-Up>    <C-w>k
>
>   nmap <xF1> <C-Right>
>   nmap <xF2> <C-Left>
>   nmap <xF3> <C-Down>
>   nmap <xF4> <C-Up>
>
> Now Esc won't "wait".
>
> See
>
>   :help 'ttimeoutlen'
>   :help <xF1>
>
> HTH :)
> --
> Gerald
>

What does the     nnoremap <C-Right> <C-w>l  and
nmap ^[Oc <C-Right> really represent?


[Pardon me if you know this already, Vijendra :) I'll take this from the
top. Sorry for the long post, but I felt it's necessary.]

First, you should understand the difference between a map and a noremap.
With a noremap, any keystrokes on the right-hand side (RHS) will be
interpreted as original Vim keystrokes. By "original", I mean that Vim
remembers the default actions of every keystroke. For example, with

  nnoremap <F2> G

hitting 'F2' will bring the cursor to the last line.

With a map, the RHS will incorporate other maps and noremaps, if they
exist. For example, we add:

  nmap G google

Now, hitting 'G' is the same as typing 'google'. But hitting 'F2' still
takes you to the last line. If the previous noremap was a map instead:

  nmap <F2> G

then hitting 'F2' will be the same as typing 'google', because hitting
'F2' would mean hitting 'G' would mean typing 'google'.

OK, that covers the map association part. Now about Vim's internal
representation of keycodes.. As you are probably aware, applications can
read keyboard input via what is known as keycodes. For example, an
application sees typing Ctrl-Right_arrow as a keycode of "^[Oc".

Unfortunately, keycodes are not standardized. They differ for each
terminal and/or OS setting. Since Vim works on multiple platforms, it
attempts to unite the representation of keycodes with an intuitive
nomenclature (e.g. <C-Right>, <C-a>, <A-F4>, <C-A-LeftMouse>).

Vim will try its best to recognize the keycodes for your platform.
Sometimes, it fails. In your case, Vim does not understand that "^[Oc"
means <C-Right>. And so you use this

  map ^[Oc ^Wl

which is the same as

  map ^[Oc <C-w>l

Now Vim, in terminal mode only (since "^[Oc" only shows up in terminal
mode), "understands" that when you type Ctrl-Right_arrow, it needs to do
a Ctrl-w + l.

But GVim still doesn't understand what to do when you type
Ctrl-Right_arrow. It never sees "^[Oc".

Hence, the way to make both Vim and GVim "understand" is to use Vim's
internal keycodes for everything. Then assign terminal/OS-specific
keycodes to Vim's internal keycodes on a platform case-by-case basis.

First we start with

  nnoremap <C-Right> <C-w>l

that tells Vim & GVim to do an "original" Ctrl-w + l when it encounters
a Ctrl-Right_arrow.

Then we do

  nmap ^[Oc <C-Right>

for Vim's sake only. This bridges your terminal's Ctrl-Right_arrow to
Vim's Ctrl-Right_arrow.

Hope this explains what you wanted to know. If not, please feel free to
ask the mailing list :)

--
Gerald

Reply via email to