Make Backspace Work in emacs-eat
This post details my troubleshooting process for a specific issue I encountered while setting emacs-eat. For those unfamiliar, emacs-eat is a(nother) terminal emulator designed to run directly within Emacs. Even though it was functional for the most part after following the installation instructions, there was one major hurdle: the backspace key wasn't working.
Now, I'm genuinely confused about terminal emulators and the machinery behind it, so take the following as just a hint of where to look. I have no explanations why the setup wasn't correct in the first place and why my seemingly incomplete solution works.
Web search didn't lead to a specific solution. Some people had the problem and fixed it by changing TERM or eat-term-name or re-compiling the .terminfo files. None of that worked for me.
TERMINFO?
So, starting from scratch, I went to the documentation. It goes through some common problems, one of which applied to my configuration: $TERMINFO differed from eat-term-terminfo-directory. Now, I don't want to break my native terminal so to fix this, but I found that emacs sets INSIDE_EMACS and I can test for that:
if string match --quiet "*,eat*" "$INSIDE_EMACS"
set -gx TERMINFO "[...]/straight/build-30.1/eat/terminfo"
end
Note: Far from perfect since this path is version dependent, so it will break as I update emacs…
But that didn't work; backspace still did nothing.
stty -a?
A bit more search tells me I should check the output of stty -a.
stty -aspeed 9600 baud; 74 rows; 108 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc
iflags: -istrip icrnl -inlcr -igncr -ixon -ixoff ixany imaxbel -iutf8
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
eol2 = <undef>; erase = <undef>; intr = ^C; kill = <undef>;
lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q;
status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;
For reference, in iterm2 + fish:
speed 38400 baud; 74 rows; 318 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc
iflags: -istrip icrnl -inlcr -igncr -ixon -ixoff ixany imaxbel iutf8
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
stop = ^S; susp = ^Z; time = 0; werase = ^W;
so erase is <undef> in eat. Why? No clue but OK let's define it to ^H:
stty erase '^H'
Nope, doesn't work. ^? neither. But let's leave it as ^? since it's the same as in iterm2 for the time being and look for another possible solution.
fish_key_reader enters the room
A bit more searching, this time focusing on fish. I find a clue that there's a fish_key_reader function:
╰─>$ fish_key_reader
Press a key:
bind delete 'do something'
It doesn't show any binding (not sure if it should, it doesn't show). Let's see in iterm2:
╰─>$ fish_key_reader
Press a key:
bind backspace 'do something'
No binding either, but the key it receives is different. OK, anyway let's try to bind it then with bind delete backward-delete-char.
Oh it works 🎉
Hmm, let's remove the stty erase, setting it back to <undef>. It still works….🧐🙄😮💨🤷♂️ I give up and settle on:
- I keep the
TERMINFOsetting since it's the documentation's recommendation. - I don't keep the
sttysetting since it seems unnecessary. - I keep the
bind, obviously.
Unresolved questions:
- I don't know why the
sttysetting isn't set or isn't needed. - I don't know why through
emacs,fishreceive thedeleteevent and notbackspacethough that's probablyeatdoing its think but then I'd expect it to be more documented, unless it's a specificeat*fishthing.