XTerm, modified keys, proper CSI parsing

63 views
Skip to first unread message

Paul LeoNerd Evans

unread,
Jan 23, 2008, 12:57:32 PM1/23/08
to vim...@googlegroups.com
Exec summary:

Vim doesn't parse XTerm's modified keys properly, so things like
<Ctrl-PageDown> don't work.


Bigger summary:

XTerm has a fairly generic mechanism for sending modified keys. Keys
like <Ctrl-PageDown>, which used not to have a representation, now do.
To parse these properly, Vim needs a full CSI-aware parser. It cannot
continue to live with a term{cap/info}-driven prefix parser. Fixing this
by adding a proper CSI parser would allow Vim to recognise any of
XTerm's modified keys. These keys allow arbitrary modifier marking of
arbitrary cursor or function keys.

-----

The way XTerm represents these keys is to use the second position
parameter of CSIs. For example, PageDown is CSI 6~, Insert is CSI 2~,
Left is CSI D, and so on. XTerm extends this in the second parameter,
with a 1+bitmask representation (because unmodified, the value defaults
to being 1).

CSI 1 ; 1 D <Left>
CSI 1 ; 2 D <Shift-Left> 1=shift; 1+1=2
CSI 1 ; 3 D <Alt-Left> 2=alt; 1+2=3
CSI 1 ; 4 D <Shift-Alt-Left>
CSI 1 ; 5 D <Ctrl-Left> 4=ctrl
...

CSI 6 ; 1 ~ <PageDown>
CSI 6 ; 2 ~ <Shift-PageDown>
CSI 6 ; 3 ~ <Alt-PageDown>
...

and so on

Currently vim doesn't understand these, prefixes don't match, and it
gets all confused e.g. noticing the CSI 1 ; doesn't match anything,
stops there, sees 5D in normal mode and deletes 5 lines of your text.

To fix this, Vim needs to acquire a proper CSI parser. This would be
able to pull out the arguments from the sequences, and apply them
accordingly.

This has to be a real parser, not just string prefix matching.

1: Because the orthoginallity of the mappings leads it to easily handle
more cases.. E.g. if a new modifier <Super-> is ever defined, say,
with a bitmask of 8, then just adding that one case to the parser
allows any modified key to use it.

2: Because these sequences have meaning, they're not just opaque
strings. See ECMA-48.
Specifically, these all mean the same thing

CSI 1 ; 3 D
CSI 001 ; 03 D
CSI 001 ; 03 ; D

Having a real parser in Vim would make the scheme much more
futureproof - the whole reason it breaks currently is the prefix
mapping. (Other applications e.g. irssi and readline do the same
thing). A proper parser could pull out all the parameters as decimal
numbers, and treat them properly. If one day a meaning is defined
for the third parameter, say, when everyone has pressure sensitive
keyboards that report a force, Vim can still cope with the new
sequences even if it doesn't understand them. By the same token, a
CSI parser that doesn't know about the modifiers would have just
ignored their presence, rather than giving up entirely.

I don't know the internals of Vim, but suggestion on #vim/Freenode said
that it doesn't have an internal representation of modified keys.

To fix this issue reallyproperly, and do nice things with GUI Vim as
well, I might suggest that keys be allowed to live in a struct something
like:


struct keypress {
int codepoint; // For normal keys
enum specialkey specialkey; // For cursor keys, function keys, etc..

int is_shift:1;
int is_alt:1;
int is_ctrl:1;
...
};

XTerm has plans for making arbitrary keys arbitrarily modifyable - it
would be great if Vim could :map any of these.

--
Paul "LeoNerd" Evans

leo...@leonerd.org.uk
ICQ# 4135350 | Registered Linux# 179460
http://www.leonerd.org.uk/

signature.asc

Bram Moolenaar

unread,
Jan 23, 2008, 4:56:43 PM1/23/08
to Paul LeoNerd Evans, vim...@googlegroups.com

Paul LeoNerd Evans wrote:

Did you check :help xterm-modifier-keys ?

What version of Vim are you talking about?

--
If you don't get everything you want, think of
everything you didn't get and don't want.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Paul LeoNerd Evans

unread,
Jan 23, 2008, 6:13:16 PM1/23/08
to vim...@googlegroups.com
On Wed, 23 Jan 2008 22:56:43 +0100
Bram Moolenaar <Br...@moolenaar.net> wrote:

> Did you check :help xterm-modifier-keys ?

> What version of Vim are you talking about?

Ahh.. That's a relatively new addition... This is an issue I've been
pondering over for a few years now, collecting up things to send to
various groups (vim being just one; I have irssi and readline on my list
too). I guess that didn't exist last time I saw.


I tried vim -e NONE -E NONE

:set <Home> gives ^[[1;*H

So I

:imap <Ctrl-Shift-Home> You typed ctrl-shift-home

Then go to insert mode, and type the key combo. Instead of inserting that
text, it performs identically to if I slowly type <Esc> [ 1 ; 6 H.

Perhaps I've missed something?

signature.asc

Paul LeoNerd Evans

unread,
Jan 23, 2008, 6:32:25 PM1/23/08
to vim...@googlegroups.com
On Wed, 23 Jan 2008 23:13:16 +0000
Paul LeoNerd Evans <leo...@leonerd.org.uk> wrote:

> I tried vim -e NONE -E NONE

Sorry; what am I on here? :) That was -u NONE -U NONE

For the record:

:version
VIM - Vi IMproved 7.1 (2007 May 12, compiled Dec 18 2007 15:29:11)
Included patches: 1-175
Compiled by jame...@debian.org

(standard debian "vim-gtk" package)

signature.asc

Paul LeoNerd Evans

unread,
Jan 23, 2008, 6:40:25 PM1/23/08
to vim...@googlegroups.com
On Wed, 23 Jan 2008 23:13:16 +0000
Paul LeoNerd Evans <leo...@leonerd.org.uk> wrote:

> :imap <Ctrl-Shift-Home> You typed ctrl-shift-home

OK, now that one's just me being a fool - it should be <C-S-Home>

Further, if I do that with :set nocp, it works as expected.


Sorry for the panic :)

signature.asc
Reply all
Reply to author
Forward
0 new messages