[drafted a while ago, but sending now that the thread got bumped; might
be a bit roughdraftish]
On Fri, 25 Feb 2011, Bram Moolenaar wrote:
This is my first time joining a discussion, I had a hard time just to
open an account and send my suggestion. I use the default reply
function and I don't mean to upset anyone. Hopefull now this reply is
well-edited (I removed the quote).
About vim, I misunderstood that it was a keyboard problem. As Bram
said it is internally set as <CTRL-I> = <Tab> and people requesting
having structured input mechanism, all I can think of is to break
apart all internal linkages and revert to the their original
settings:
I found that <CTRL-M> and <Enter> both have the same keymap code
0x0d, and both <Tab> and <CTRL-I> gives 0x09, maybe that is why vim
gives the same output.
[...]
So the problem is that many users expect CTRL-M to have the same
effect as Enter, just like people use CTRL-[ instead of Esc. And a
few people would make the CTRL-M act different from Enter, and CTRL-[
different from Esc.
First problem is to actually detect what key was pressed, in most
terminal emulators this is not possible. In the GUI we can. Changing
terminal emulators to support this and making this work with Vim is a
separate issue, I'll not go into that here.
Then we need a way to make the extra information available to be used
in mappings, without breaking it for users relying on the current way.
Some things that are no acceptable:
- Have a setting to enable "the new way". This will break existing
stuff and make users pull their hair out because they don't know this
setting exists. Forget it.
- Change the input queue from a stream of bytes to some list of structs.
This isn't adding any functionality and breaks all kinds of mapping
and termcode handling, register execution, etc. Forget it.
What we can do is extend the existing modifier byte sequence. This is
a bit tricky, but it should work. So we add a new byte sequence with
the raw key encoded, plus modifiers. Thus for CTRL-[ you get the [
key with the CTRL modifier.
When this new modifier is not mapped, it is discarded and the
following translated codes are used normally, just like now. Thus
without any mappings that use the new modifier it is guaranteed to
work as before. When executing a register where the new modifiers are
missing it works just like before.
When a new modifier is mapped, it is replaced by what it's mapped to,
AND the following old style byte sequence is consumed.
An alternative is to let the termcap handling translate the new
modifer into the old style key. That works because mappings are
applied both to the raw escape sequences and on the key codes they are
converted to.
We also need a way to specify mappings with the new modifier, perhaps
using a special modifier X, thus you could do:
:map <X-C-[> :echo CTRL-[<CR>
:map <X-C-I> :echo CTRL-I<CR>
So, instead of enabling a single setting (usenewkeymaps or whatever),
the :map command needs a new "Yes, do what I'm telling you to do"
modifier? This seems totally backwards to me. The "new way" will cause
problems with old stuff. Why is that breakage unacceptable? This whole
suggestion seems like a major-version change anyway (not a point-version
change, where backwards compatibility is sacrosanct). The stuff it's
breaking was caused by having to do a workaround in the first place.
Consider:
" {intent} should do {rhs}
:map {lhs} {rhs}
Where {intent} describes the intended binding (what key should be
pressed to activate it), and {lhs} is what was actually typed. In the
following chart, {around} indicates that the only reason that particular
{lhs} was chosen was to work around the limitation of key mappings.
{new-works} indicates that using that same {lhs} would still work under
the "new way". (^x indicates entering a literal control character)
{intent} | {lhs} | {around} | {new-works} | Category
---------+---------+----------+-------------+---------
<Enter> | <C-m> | yes | no | Enter vs Ctrl+m
<Enter> | <Enter> | no | yes
<Enter> | ^M | yes | no(?)
<C-m> | <C-m> | no | yes
<C-m> | <Enter> | ? | no
<C-m> | ^M | yes | yes(?)
---------+---------+----------+-------------+---------
<Esc> | <C-[> | ? | no | Esc vs Ctrl+[
<Esc> | <Esc> | no | yes
<Esc> | ^[ | yes | no(?)
<C-[> | <C-[> | no | yes
<C-[> | <Esc> | ? | no
<C-[> | ^[ | yes | yes(?)
---------+---------+----------+-------------+---------
<Tab> | <C-i> | yes | no | Tab vs Ctrl-i
<Tab> | <Tab> | no | yes
<Tab> | ^I | yes | no(?)
<C-i> | <C-i> | no | yes
<C-i> | <Tab> | ? | no
<C-i> | ^I | yes | yes(?)
---------+---------+----------+-------------+---------
é | <M-i> | yes | no | é vs Alt/Meta-i
é | é | no | yes | (issue w/ 8th-bit meta)
<M-i> | <M-i> | no | yes
<M-i> | é | yes | no
Not sure if the chart is clear, but my point is:
I think that the people who expect, e.g., <C-i> to activate a <Tab>
mapping are the people who either:
1. Know what's going on behind the scenes, so are knowledgeable enough
to fix their mappings (fixing plugin mappings is a separate issue)
2. Were bitten by something that didn't work right, but found a
workaround and only use it due to inertia.
I highly doubt there are people who approach the :map command with the
*desire* that <C-i> or ^I would activate a :map whose {lhs} contains
<Tab> or that <Tab> would activate a <C-i> :map. This seems like a
clear case where backwards compatibility is undesirable.
The fact that plugins probably rely on this behavior is unfortunate, but
"Oh, that plugin's <Tab> binding is broken because Vim's key mapping
used to be broken, and so it was using the Ctrl-i workaround" seems like
a preferable position to be in.
--
Best,
Ben
--
You received this message from the "vim_dev" 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