On Mon, 12 Nov 2007 14:22:21 -0800
Gautam Iyer <[EMAIL PROTECTED]> wrote:

> especially when I press them with a modifier
> (e.g. Control+Left/Right).

That's a separate issue, entirely unrelated to the number of colours.

It's been somewhat of a hobbyhorse of mine for a few years - I've made
some notes on the subject:

   http://home.leonerd.org.uk/local/terminal.html

------

Vim has trouble parsing the way newer XTerms encode modified cursor keys
(that's Up/Down/Left/Right, Insert/Del/Home/End/PageUp/PageDown, and
others, combined with Ctrl/Shift/Alt/Hyper/Super/... modifier keys).

This problem comes from the way that 'terminfo' basically just provides a
static mapping from byte sequences into a big enumeration of key
constants. The way xterm encodes it doesn't work like this.

Xterm uses the CSIs the encode cursor movement or function keys, and
provides extra parameters.

[[A brief introduction to CSIs: 

A CSI is basically a procedure call - it has a method name and some
(possibly none) parameters. The name is a single character in the range
[\x40-\x7e], and the parameters are semicolon-separated numbers. CSIs are
used to send control sequences from the application, into the terminal.

The CSI for "move cursor up", for example is usually encoded

  CSI A

It includes a number parameter to give it a count, defaulting to 1. This
CSI does not give meanings for any of the other positional parameters. If
a parameter is missing, it is presumed to have its default value - this
is how "CSI A" alone can stand for it. Other valid encodings could be

  CSI ; A
  CSI 1 A
  CSI 1 ; A
  etc...

All of these mean "move up 1 position".

When terminals started gaining extra keys like cursor movement keys, that
do not have standard ASCII mappings, these CSIs were extended to encode
keys back into the application. CSI A/B/C/D encode up/down/right/left.
For most of the other "special" keys (such as F1-F12 and
PageUp/PageDown), a more generic mechanism instead is used, where they
are given function numbers, and the "~" CSI is used. This takes one
parameter, the function key number. PageUp / PageDown are given 5 and 6.
A "PageUp" key is thus encoded

  CSI 5 ~

Equally valid, are any of the other ways to encode this CSI

  CSI 5 ; ~
  CSI 5 ; 1 ~
  CSI 5 ; ; ; ; ~
  etc...
]]

To represent modified movement keys or function keys, xterm uses the
second position of the various CSIs normally used, to encode the modifier
bitmask. A default of "1" is assumed to be in effect if not otherwise
specified, so the encoding uses a 1+bitmask scheme:

  1 = no modifier
  2 = shift
  3 = alt
  4 = shift+alt
  5 = ctrl
  6 = shift+ctrl
  7 = alt+ctrl
  8 = shift+alt+ctrl
  etc...

This is placed in the second CSI parameter. So, Alt-Left and
Alt-PageDown might be encoded as

  CSI 1 ; 3 D
  CSI 5 ; 3 ~

This scheme generalises - any function key or movement key can be
combined with any modifier.

Vim has a problem parsing these currently, because of (I believe)
inflexibilities in terminfo. It only has a static mapping from bytes into
the key enumeration. It cannot parameterise the modifier bits.

While it could be possible to give a large list of K*2^M mappings (for K
keys and M possible modifiers), a more efficient scheme ought to be
sought, where Vim could directly parse the CSI sequences. This would also
avoid the current failure mode.

The current failure is that, for example, when xterm sends a Ctrl-Left
key, it sends

  CSI 1 ; 5 D

Vim reads that as far as the semicolon, and finds it doesn't correspond
to any valid key sequence, so instead interprets it as "5D", which
results in 5 lines of text being deleted.

I would like to assist in fixing this issue, but I'm not really sure
where to start, code-wise. Should Vim somehow have a special case for CSI
parsing, if it recognises the $TERM is one that sends CSIs, and use that
instead? What makes xterm "special" here? Would other terminals do it?

Should terminfo be somehow extended? This seems less desirable - given
the arbitrary way CSI parameters can be sent, it would seem useful to
have some form of parsing logic that can pull apart the parameters,
whatever they may be, even if the logic beyond that just ignores them.
This would at least avoid problems in the future, if a meaning for the
3rd position was ever given, for example.

Or maybe some new keyboard-input parsing library needs to be provided,
that can be used beyond vim, into any program that reads keyboard input
and would care about modifiers. Even if not, it would help to avoid for
example readline's failure to handle the same CSIs when running handling
input for bash.

-- 
Paul "LeoNerd" Evans

[EMAIL PROTECTED]
ICQ# 4135350       |  Registered Linux# 179460
http://www.leonerd.org.uk/

Attachment: signature.asc
Description: PGP signature

Raspunde prin e-mail lui