diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/zle_keymap.c | 86 | ||||
-rw-r--r-- | Src/init.c | 3 | ||||
-rw-r--r-- | Src/zsh.h | 6 |
3 files changed, 74 insertions, 21 deletions
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 28203655e..b46c74f91 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1011,6 +1011,56 @@ cleanup_keymaps(void) zfree(keybuf, keybufsz); } +static char *cursorptr; + +/* utility function for termcap output routine to add to string */ + +static int +add_cursor_char(int c) +{ + *cursorptr++ = c; + return 0; +} + +/* interrogate termcap for cursor keys and add bindings to keymap */ + +/**/ +static void +add_cursor_key(Keymap km, int tccode, Thingy thingy, int defchar) +{ + char buf[2048]; + + /* + * Be careful not to try too hard with bindings for dubious or + * dysfunctional terminals. + */ + if (tccan(tccode) && !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) { + /* + * We can use the real termcap sequence. We need to + * persuade termcap to output `move cursor 1 char' and capture it. + */ + cursorptr = buf; + tputs(tcstr[tccode], 1, add_cursor_char); + *cursorptr = '\0'; + } else { + /* Assume the normal VT100-like values. */ + sprintf(buf, "\33[%c", defchar); + } + bindkey(km, buf, refthingy(thingy), NULL); + + /* + * If the string looked like \e[? or \eO?, bind the other one, too. + * This is necessary to make cursor keys work on many xterms with + * both normal and application modes. + */ + if (buf[0] == '\33' && (buf[1] == '[' || buf[1] == 'O') && + buf[2] && !buf[3]) + { + buf[1] = (buf[1] == '[') ? 'O' : '['; + bindkey(km, buf, refthingy(thingy), NULL); + } +} + /* Create the default keymaps. For efficiency reasons, this function * * assigns directly to the km->first array. It knows that there are no * * prefix bindings in the way, and that it is using a simple keymap. */ @@ -1023,6 +1073,7 @@ default_bindings(void) Keymap emap = newkeymap(NULL, "emacs"); Keymap amap = newkeymap(NULL, "vicmd"); Keymap smap = newkeymap(NULL, ".safe"); + Keymap vimaps[2], kptr; char buf[3], *ed; int i; @@ -1066,25 +1117,22 @@ default_bindings(void) /* vt100 arrow keys are bound by default, for historical reasons. * * Both standard and keypad modes are supported. */ - /* vi command mode: arrow keys */ - bindkey(amap, "\33[A", refthingy(t_uplineorhistory), NULL); - bindkey(amap, "\33[B", refthingy(t_downlineorhistory), NULL); - bindkey(amap, "\33[C", refthingy(t_viforwardchar), NULL); - bindkey(amap, "\33[D", refthingy(t_vibackwardchar), NULL); - bindkey(amap, "\33OA", refthingy(t_uplineorhistory), NULL); - bindkey(amap, "\33OB", refthingy(t_downlineorhistory), NULL); - bindkey(amap, "\33OC", refthingy(t_viforwardchar), NULL); - bindkey(amap, "\33OD", refthingy(t_vibackwardchar), NULL); - - /* emacs mode: arrow keys */ - bindkey(emap, "\33[A", refthingy(t_uplineorhistory), NULL); - bindkey(emap, "\33[B", refthingy(t_downlineorhistory), NULL); - bindkey(emap, "\33[C", refthingy(t_forwardchar), NULL); - bindkey(emap, "\33[D", refthingy(t_backwardchar), NULL); - bindkey(emap, "\33OA", refthingy(t_uplineorhistory), NULL); - bindkey(emap, "\33OB", refthingy(t_downlineorhistory), NULL); - bindkey(emap, "\33OC", refthingy(t_forwardchar), NULL); - bindkey(emap, "\33OD", refthingy(t_backwardchar), NULL); + vimaps[0] = vmap; + vimaps[1] = amap; + for (i = 0; i < 2; i++) { + kptr = vimaps[i]; + /* vi command and insert modes: arrow keys */ + add_cursor_key(kptr, TCUPCURSOR, t_uplineorhistory, 'A'); + add_cursor_key(kptr, TCDOWNCURSOR, t_downlineorhistory, 'B'); + add_cursor_key(kptr, TCLEFTCURSOR, t_vibackwardchar, 'D'); + add_cursor_key(kptr, TCRIGHTCURSOR, t_viforwardchar, 'C'); + } + + /* emacs mode: arrow keys */ + add_cursor_key(emap, TCUPCURSOR, t_uplineorhistory, 'A'); + add_cursor_key(emap, TCDOWNCURSOR, t_downlineorhistory, 'B'); + add_cursor_key(emap, TCLEFTCURSOR, t_backwardchar, 'D'); + add_cursor_key(emap, TCRIGHTCURSOR, t_forwardchar, 'C'); /* emacs mode: ^X sequences */ bindkey(emap, "\30*", refthingy(t_expandword), NULL); diff --git a/Src/init.c b/Src/init.c index b07ac80d5..a0c06aa63 100644 --- a/Src/init.c +++ b/Src/init.c @@ -497,7 +497,8 @@ init_shout(void) static char *tccapnams[TC_COUNT] = { "cl", "le", "LE", "nd", "RI", "up", "UP", "do", "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta", - "md", "so", "us", "me", "se", "ue", "ch" + "md", "so", "us", "me", "se", "ue", "ch", + "ku", "kd", "kl", "kr" }; /* Initialise termcap */ diff --git a/Src/zsh.h b/Src/zsh.h index baafdb0e6..315c1d3bd 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1524,7 +1524,11 @@ struct ttyinfo { #define TCSTANDOUTEND 22 #define TCUNDERLINEEND 23 #define TCHORIZPOS 24 -#define TC_COUNT 25 +#define TCUPCURSOR 25 +#define TCDOWNCURSOR 26 +#define TCLEFTCURSOR 27 +#define TCRIGHTCURSOR 28 +#define TC_COUNT 29 #define tccan(X) (tclen[X]) |