Zsh, rxvt-unicode & escape sequences


#1

Hello everyone

I’ve been using linux, mostly arch, for a very long time and decided to try out ArchLabs yesterday and I’m really happy with how it’s set up. I’m running the i3 variant.

However this thing is driving me crazy and I can’t find a good way to fix it. As an AL newbie I’d rather not fiddle with too many config files before I get accustomed to how things work here since I might end up overriding some settings elsewhere.

But this is something I need to have working right away…so. How do I get my setup to behave like gnome-terminal for example? By default when I press ctrl-left i go back one word and pressing the end key takes me to the end of the line in most terminals and setups.

Why on earth do I run into this issue with my current setup? I’d really appreciate a simple explanation on why URxvt has decided to be not like the others? It just feels so ridiculous but there must be a valid reason.

So what’s the right way (on AL particularily) to set this up so that I can open a terminal and have all these keys do what they’re supposed to do? TBH I’m not even sure if this is a zsh or URxvt issue or maybe something else.

So sorry for venting but this thing triggers me much more than it should.

Thanks for reading!


ZSH bindings behave strangely out of the box
#2

Hello,

Yea urxvt has some issues. It is much older than most terminals and certainly than vte based ones (like gnome-terminal) so it has many reasons for the way it is, an excerpt from wikipedia

Features[edit]

Aside from features such as those controlled by resource files, rxvt’ s terminal emulation differs from xterm in two important ways:

  • It emulates a VT102, rather than a VT220. That means that it handles 8-bit data differently, does not implement the C1 controls that xterm does. xterm des implement a switch “-k8”[3] to suppress that functionality; rxvt does not provide an option to emulate a VT220.
  • The strings sent for function keys are different. xterm sends strings that are encoded using the same rules as the ANSI/ISO escape sequences. Rxvt’ s do not, though they provide comparable flexibility in this area.

Newer versions of rxvt have primitive support for pseudo-transparency.

The rxvt distribution also includes an analog clock program called rclock. Very old distributions included a copy of vttest, but dropped that in 1996 with version 2.18.


You’ve got a few possible solutions

  1. Create a shell bind for the key sequence. Using <Ctrl-v> then pressing the key sequence will let you see the actual sequence output from the terminal. eg. <Ctrl-Left> in my terminal is ^[[1;5D. This can then be bound to an action using zsh’s bindkey, eg. to get the ctrl-left jumping back words
    bindkey '^[[1;5D' backward-word
    
  2. Use rxvt’s built in settings to do nearly the same as above but in ~/.Xresources instead of shell config, see here for exactly what you want in an example.
  3. Install a vte based terminal emulator instead like gnome-terminal, termite, xfce4-terminal, etc…

You can also check out ~/.zsh/** for the default AL zsh stuff, some good examples in there as well.

Cheers


#3

Thank you! Good info.

Termite looks good to me, I could definitely switch but I’m having the same issue there too and gnome-terminal as well.

I’m really confused about this. I can’t remember exactly but maybe I chose a bad keyboard variant in the install script? This is a Thinkpad T440s.

localectl status
System Locale: LANG=en_US.UTF-8
VC Keymap: fi
X11 Layout: fi

setxkbmap -print -verbose 10
Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev…
Trying to load rules file /usr/share/X11/xkb/rules/evdev…
Success.
Applied rules from evdev:
rules: evdev
model: pc105
layout: fi
variant: classic
Trying to build keymap using the following components:
keycodes: evdev+aliases(qwerty)
types: complete
compat: complete
symbols: pc+fi(classic)+inet(evdev)
geometry: pc(pc105)
xkb_keymap {
xkb_keycodes { include “evdev+aliases(qwerty)” };
xkb_types { include “complete” };
xkb_compat { include “complete” };
xkb_symbols { include “pc+fi(classic)+inet(evdev)” };
xkb_geometry { include “pc(pc105)” };

cat /etc/X11/xorg.conf.d/00-keyboard.conf
Section “InputClass”
Identifier “system-keyboard”
MatchIsKeyboard “on”
Option “XkbLayout” “fi”
EndSection

XFCE keyboard settings are set to follow system defaults.

Thanks!


#4

Was this the keymap you selected?

Moving forward lets clear up exactly what is happening and what you would like to have happen.


#5

this also strikes me as off, check /etc/locale.gen make sure your language of preference is uncommented and that en_US.UTF-8 is as well, then run locale-gen as root.


#6

I want English language everywhere & a Finnish keyboard layout with functioning home/end/delete keys and others for easier command line editing, such as Ctrl-left

en_US.UTF-8 is the only uncommented locale. I did run locale-gen again to be sure (no effect).


#7

So if you open whichever terminal you’re using and type <Ctrl-v> then enter the key sequence you want to use, paste what it outputs here for each with what action you want and I’ll post some bind commands.

Unless you think this issue is unrelated and locale based, I just haven’t seen any reason to think so. If you’re having issues in other applications as well then it would be different.

Let me show you what I use personally with st, as there really is no clear cut way to handle terminal escape sequences across all cases.

# terminfo keys
autoload -U terminfo

# better history navigation
autoload -U up-line-or-beginning-search; zle -N up-line-or-beginning-search
autoload -U down-line-or-beginning-search; zle -N down-line-or-beginning-search

# setup some key bindings
bindkey -- '^P' up-history
bindkey -- '^N' down-history
bindkey -- '^E' end-of-line
bindkey -- '^A' beginning-of-line
bindkey -- '^K' up-line-or-beginning-search
bindkey -- '^J' down-line-or-beginning-search
bindkey -- '^[^M' self-insert-unmeta # alt-enter
bindkey -- "${terminfo[kend]}" end-of-line # end
bindkey -- "${terminfo[kdch1]}" delete-char # delete
bindkey -- "${terminfo[kich1]}" overwrite-mode # insert
bindkey -- "${terminfo[khome]}" beginning-of-line # home
bindkey -- "${terminfo[kcub1]}" backward-char # left arrow
bindkey -- "${terminfo[kcuf1]}" forward-char # right arrow
bindkey -- "${terminfo[kbs]}" backward-delete-char # backspace
bindkey -- "${terminfo[kcbt]}" reverse-menu-complete # shift-tab
bindkey -- "${terminfo[kcuu1]}" up-line-or-beginning-search # up arrow
bindkey -- "${terminfo[kcud1]}" down-line-or-beginning-search # down arrow

Also of note is that not all terminals will support terminfo either, it just so happens that mine does. If I don’t bind some of these then the sequences aren’t interpreted correctly and you get some funny behaviour, like insert deleting some characters and inserting a ~, etc…


#8

Thanks. Since .zsh/settings/bindings.zsh already has relevant entries I’m not sure why this problem still persists. I’d like to find the root cause and stick to the defaults as much as possible.

Home-key: ^[OH
Left-key: ^[OD

Etc.

I actually had to install Windows today just to update my Thinkpad Pro Dock firmware so I decided to reinstall AL, just with fewer packages. I use Termite exclusively now since it does everything I need.

Thanks again, I appreciate your help a lot, this is quite confusing!


#9

I ended up adding these lines to ~.zsh/settings/bindings.zsh:

#Ctrl-arrow keys
bindkey ‘^[[1;5D’ backward-word
bindkey ‘^[[1;5C’ forward-word

#Delete-key
bindkey ‘^[[3~’ delete-char

#Home/End keys
bindkey ‘^[OH’ beginning-of-line
bindkey ‘^[OF’ end-of-line

This is fine but I’d rather find a better solution if it exists. Many thanks!


#10

Sorry <Ctrl-Arrow> (among others) are non-standard sequences in the terminfo spec.


Regarding the above bindings (not ctrl-*, but the home, end, delete), did you first autoload -U terminfo before trying to use ${terminfo[XXX]}, termite does have a terminfo entry, so the defaults provided in bindings.zsh or my above example should work for those keys.

pacman -S termite-terminfo

You can examine the terminfo entry for your terminal with infocmp -x and you will either just have to know the name of the entry or compare the sequences, see man terminfo in the Predefined Capabilities section.


#11

Do they really not offer another flashing solution aside from installing another os? Not a harp on windows at all, just usually with firmware they make it available to most os’


#12

Hah, nope! But there’s this ongoing project that might change things for the future: https://fwupd.org/

And just downloading the firmware .exe wasn’t enough, it errored out several times for various reasons so I had to install the Lenovo update tool, download and install every driver, reboot several times and only then would the firmware be updated correctly. But now it’s done and my external display seems to work as it should.


#13

Hey, as long as it works it’s a plus.


#14

Yup, bindings.zsh does that from what I can tell.

<Ctrl-V> Home prints ^[OH

and

infocmp -x | \grep --color=auto OH prints kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,

Guess I should just rtfm but can you give a quick explanation on what’s happening here?

That’s F8, F9, Home and insert-character key all on the same line.


#15

infocmp just parses the compiled database for the current terminal and prints it out, it’s perfectly fine to have many entries on the same line. The \E is the escape character ^[ (it’s all one character but the browser makes it into printable ^ and [) you can also freely use the escape in binds and the shell will translate it, so \E[2~ and ^[[2~ are the same thing.

I’m honestly not sure why it would need anything else on your side other than the Ctrl binds. I’ll do a bit of looking around.

After installing termite and fiddling with it for a bit it seems to work fine on my end (very strange) some of the sequences differ but that shouldn’t matter, all the binds (insert, home, etc…) are working, essentially after this I’m no less confused :stuck_out_tongue: