On Mon, Feb 4, 2008 at 4:55 PM, [EMAIL PROTECTED] wrote:
>
> On Jan 12, 1:57 pm, "Matt Wozniski" wrote:
> >
> > On Jan 12, 2008 12:49 PM, Ben Schmidt wrote:
> >
> > > > noremap <Space> <PageDown>
> > > > noremap <S-Space> <PageUp>
> >
> > > > However, in Linux, running vim inside the gnome-terminal 2.18.2 (or
> > > > when
> > > > running gvim), both space and shift-space do page-down operation. I
> > > > can't
> > > > figure out the source of this problem. Note that the exact same .vimrc
> > > > file
> > > > works perfectly in MS Windows, i.e. shift-space does page-up.
> >
> > > This isn't surprising. A lot of keys such as shift-space won't work in
> terminals,
> > > but only in the Vim GUI (gvim or vim -g). In a terminal, both space and
> > > shift-space produce the same code, so Vim can't tell the difference.
> >
> > > If you are under Gnome, maybe try compiling in the GTK/GTK2 GUI of Vim;
> that would
> > > probably work.
> >
> > Certainly would fix the keybinding problem, anyway.
If anyone remembers this thread, the OP complained that he could
neither get <s-space> to be recognized independently of <space> in vim
nor in a GTK2 or Gnome2 gvim. I gave him a solution to get it to work
in vim in at least one terminal (xterm, the best terminal ;) ), but
noted that he was right - I could map it in vim after that trick, but
not in gvim. Now that I got some time to dig around and figure out
why, I came to the conclusion that <s-space> is completely un-mappable
if we compiled using GTK2 and XIM. The reason is simple: we use XIM
to translate a keypress into a sequence of UTF-8 bytes wherever
appropriate. So, if <space> is pressed, XIM says "this key
corresponds to ASCII 0x20 -> UTF-8 0x20", and tells us to insert 0x20
into our input buffer. If <s-space> is pressed, XIM says "This key
corresponds to ASCII 0x20 (even though it's shift-modified)", and
tells us to insert 0x20 into our input buffer. After XIM tells us
that it handled the key press for us, we lose the information about
what modifiers were pressed, and only have the characters that they
correspond to. As far as I can tell, this is where <space> is a
special case: it seems to be the only key on the keyboard that both
corresponds directly to a character to display and corresponds to the
same character when shift-modified. The alpha-numerics correspond to
different characters when shifted, the function keys don't correspond
to characters at all, nor do tab, backspace, home, end, delete, etc...
So, the only key that would seem to need special casing is <s-space>.
I'm attaching a patch that fixes mapping <s-space> for me, and (for a
quick test, though I'm not a heavy XIM user) doesn't seem to break
anything. All it does is checks if the keycode is "space" and and
"shift" is pressed, fake a response from XIM saying that it can't
handle the key. This seems safe to do, since if the user pressed
<s-space> when he could have just pressed <space> to insert the same
character, he was obviously trying to give a special keypress to vim,
not to XIM.
~Matt
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
Index: mbyte.c
===================================================================
--- mbyte.c (revision 915)
+++ mbyte.c (working copy)
@@ -4166,6 +4166,21 @@
xim_ignored_char = FALSE;
}
+ /* GTK2 XIM doesn't do what we want when:
+ * 1. The key pressed corresponds directly to a unicode code point
+ * 2. The key corresponds to the same code point even when shift-modified
+ * 3. The key is shift-modified
+ *
+ * Since im_commit_cb only receives a string of utf-8 characters, and the
+ * key corresponds to the same utf-8 characters whether shifted or
+ * unshifted, the callback has no way of knowing that we were shifted. The
+ * only solution I can see is to never allow the XIM to intercept keys that
+ * meet all 3 of these criteria. Fortunately, the only key I see that
+ * meets all 3 conditions is 'space'.
+ */
+ if ((event->state & GDK_SHIFT_MASK) && (event->keyval == GDK_space))
+ return FALSE;
+
/*
* When typing fFtT, XIM may be activated. Thus it must pass
* gtk_im_context_filter_keypress() in Normal mode.