# tcsh vi-mode and history



## Mikael (May 17, 2010)

Hi,

I'm using tcsh in vi-mode and when I use the up/down arrow keys to navigate the history I'm thrown into command mode, I would like to stay in insert mode. I've tried to use bindkey to fix this but with no luck. Basically I would like to do something like the following (this does not work):

```
> bindkey -v
> bindkey -k up up-history vi-insert
```

Any ideas?

Thanks


----------



## Erratus (May 25, 2010)

If you use .cshrc there should be something like this:

```
if ($?prompt) then
        # An interactive shell -- set some stuff up
        if ( $?tcsh ) then
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
        endif
endif
```


----------



## Mikael (May 25, 2010)

Thank you for your reply Erratus but I want to use vi-mode.

To see what I'm talking about you can try the following:

```
> tcsh
> bindkey -v
> ls
```
Press UP to get the last command (ls), try to type " -al" to get (ls -al), it will not work as expected because you're in vi-command-mode.


----------



## sixtydoses (May 25, 2010)

Probably this is what you need:

```
bindkey "\e[6;5~" history-search-forward
```


----------



## Mikael (May 26, 2010)

sixtydoses, thank you that's so close but it breaks command-mode somehow (hitting ESC doesn't work anymore). Where can I find more information about bindkey and the syntax for "keys"? I've search for it a few times but it only ends in frustration :r


----------



## SirDice (May 26, 2010)

Mikael said:
			
		

> sixtydoses, thank you that's so close but it breaks command-mode somehow (hitting ESC doesn't work anymore). Where can I find more information about bindkey and the syntax for "keys"? I've search for it a few times but it only ends in frustration :r



The tcsh(1) man page is a good place to start.


----------



## Mikael (May 26, 2010)

SirDice said:
			
		

> The tcsh(1) man page is a good place to start.



Ouch  It was the first place I looked, then http://www.tcsh.org and finally Google. But I can't find a good description of key sequences like the one sixtydoses used:



> bindkey "\e[6;5~" history-search-forward


----------



## sixtydoses (May 26, 2010)

Mikael said:
			
		

> sixtydoses, thank you that's so close but it breaks command-mode somehow (hitting ESC doesn't work anymore). Where can I find more information about bindkey and the syntax for "keys"? I've search for it a few times but it only ends in frustration :r



http://www.giref.ulaval.ca/~deteix/optimisation/bindkey.tcsh

Hope that helps.


----------



## Mikael (May 27, 2010)

Thank you sixtydoses but those examples doesn't help me much. I guess I will try the tcsh mailing list or try to get used to this behavior (but that hasn't work so far).


----------



## john_doe (May 27, 2010)

Mikael said:
			
		

> I can't find a good description of key sequences like the one sixtydoses used:


You can get escape sequences for keys using *quoted-insert* editor command (usually bound to Ctrl+V). Try to type in tcsh:
Ctrl+V Ctrl+A -> ^A
Ctrl+V Alt+A -> ^[A or \eA
Ctrl+V PgDn -> ^[[6~ or \e[6~
etc.
These produced sequences can be used with *bindkey* command unmodifed. But you may want to substitute escape char:*^[* with *\e*. Escape sequences are defined in termcap(5) file, e.g. /etc/termcap, but you'll probably don't need to read it.


----------



## quiet-note (Dec 29, 2021)

My sincere apologies for replying to a nearly 12-year-old thread.  I had this same question and stumbled on this thread after much Googling (in fact, I am almost convinced this is the only place on the internet where this question is asked).  So, for anyone using vi-mode with tcsh in 2022, here is a solution (append to ~/.cshrc):


```
# Fix Arrow Keys: Do Not Leave Insert-Mode
#
# The terminal sends something like \e[A or \eOA (where \e is the escape key).
# By default (vi-mode):
#   1. \e switches to command mode.
#   2. [A or OA is a "Multi-character binding" and runs an editor command.
#
# The commands bound to the arrow keys (backward-char, up-history, down-history,
# forward-char) are the same as typing h, j, k or l in command mode.
#
# `bindkey -a -s` can be used to chain together multiple editor commands in
# command mode if the editor commands are mapped to keys.  For example, 
# `bindkey -a -s "[A" "ki" would run both up-history (k) and vi-insert (i).
# So `bindkey -a -s` can be used to re-enter insert mode (i) after running the 
# editor commands associated with the arrow keys, since those editor commands
# are mapped to h, j, k and l.

# Up
bindkey -a -s "[A" "ki"
bindkey -a -s "OA" "ki"
# Down
bindkey -a -s "[B" "ji"
bindkey -a -s "OB" "ji"
# Right
bindkey -a -s "[C" "li"
bindkey -a -s "OC" "li"
# Left
bindkey -a -s "[D" "hi"
bindkey -a -s "OD" "hi"

# `bindkey -s` does not seem to work for the arrow keys when in `~/.cshrc`.
# Solution: schedule the commands to run later.

alias fixkeys1 'bindkey -a -s "[A" "ki" ; bindkey -a -s "[B" "ji" ; bindkey -a -s "[C" "li" ; bindkey -a -s "[D" "hi"'
alias fixkeys2 'bindkey -a -s "OA" "ki" ; bindkey -a -s "OB" "ji" ; bindkey -a -s "OC" "li" ; bindkey -a -s "OD" "hi"'

sched +00:00 fixkeys1
sched +00:00 fixkeys2

# Fix Delete Key and Do Not Leave Insert Mode
# (for some reason, this one works, even when included in `~/.cshrc`

bindkey -a -s "[3~" "xi"
```


----------

